Using RecyclerView with GridLayoutManager to add dynamic buttons to a layout - java

I am adding dynamic imagebuttons to a layout in a Fragment using recyclerview with gridlayoutmanager. The buttons are added as a user performs an action, so they are not all created during onCreateView().
I seem to have to initialize my recycler view and adapter onCreateView() with a an empty imagebutton, when my app starts up. And so I do that, but it creates a little grey square like the image below.
and then when the user performs an action and the real button I want is created, the square is still present over my image button that was just created like you can see in this new image below.
DOES ANYONE KNOW HOW I CAN GET THE INITIAL EMPTY GREY IMAGE BUTTON TO NOT BE THERE AT STARTUP OR OVER MY "DriveDroid" IMAGE BUTTON?
I have tried setting the initial background of my image button to transparent (using background color = #00000000), but this seems to make a transparent image button over my DriveDroid button, so that my onClick listener for DriveDroid no longer works.
Here is how I initialize my recycler view:
public class MyFragment extends Fragment {
private GridLayoutManager lLayout;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.my_fragment, container, false);
// Create an empty list to initialize the adapter (or else get nullPointerException error)
List<ItemObject> myList = new ArrayList<ItemObject>();
lLayout = new GridLayoutManager(getActivity(), 4, GridLayoutManager.HORIZONTAL, false);
RecyclerView rView = (RecyclerView)view.findViewById(R.id.recycler_view);
rView.setHasFixedSize(true);
rView.setLayoutManager(lLayout);
RecyclerViewAdapter rcAdapter = new RecyclerViewAdapter(getActivity(),myList);
rView.setAdapter(rcAdapter);
return view;
}
And here is my layout my_fragment
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_horizontal"
android:layout_margin="5dp"
android:id="#+id/my_fragment"
>
<android.support.v7.widget.RecyclerView
android:id="#+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbars="horizontal" />
<ImageButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/new_app_button"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/new_app_name"
android:layout_below="#+id/new_app_button"
android:layout_alignStart="#+id/new_app_button"
android:layout_alignLeft="#+id/new_app_button"
android:gravity="center"
/>
</RelativeLayout>
HERE IS HOW I CHANGED MY LAYOUT TO GET IT TO WORK, IF IT HELPS ANYONE ELSE!
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_horizontal"
android:layout_marginTop="15dp"
android:id="#+id/my_fragment"
>
<android.support.v7.widget.RecyclerView
android:id="#+id/recycler_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:scrollbars="horizontal" />
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/new_app_button"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/new_app_name"
android:gravity="center"
android:layout_below="#+id/new_app_button"
/>
</RelativeLayout>
</LinearLayout>

As mentioned in the comment, that your controls was overlapping each others, you should wrap them inside linear layout or add properties to make them positioned relative to each others.
Regarding the grey button this should be related to "new_app_button"

Related

How to update style of selected item inside ViewPager?

I want to update the style of the selected item inside a ViewPager.
How can I do this?
This is the UI design. As you can see, the "November" tab is selected, so the corresponding bar is highlighted in yellow.
The way I've implemented this is a ViewPager with a custom item (white, not highlighted):
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.cardview.widget.CardView
android:layout_width="142dp"
android:layout_height="275dp"
android:layout_margin="0dp"
app:cardElevation="0dp"
app:cardBackgroundColor="#android:color/transparent">
<TextView
android:id="#+id/monthly_spend_month"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/December"
android:textColor="#color/aluminum"
android:textSize="20sp"
android:textStyle="normal"
android:layout_marginStart="22dp"
android:layout_marginTop="34dp"/>
<RelativeLayout
android:id="#+id/monthly_spend_card"
android:layout_marginTop="120dp"
android:layout_marginStart="22dp"
android:layout_width="120dp"
android:layout_height="155dp"
android:background="#drawable/monthlyspend_card_bg_inactive">
<TextView
android:id="#+id/monthly_spend_text"
android:textColor="#color/almost"
android:layout_marginTop="50dp"
android:layout_marginStart="22dp"
android:text="Total
spent"
android:textSize="#dimen/balanceDescTextSize"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:id="#+id/monthly_spend_amount"
android:textColor="#color/almost"
android:layout_marginTop="10dp"
android:layout_marginStart="22dp"
android:layout_below="#id/monthly_spend_text"
android:text="$ 254.98"
android:textSize="#dimen/balanceDescTextSize"
android:textStyle="bold"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</RelativeLayout>
</androidx.cardview.widget.CardView>
</LinearLayout>
I plan on doing the highlighting programmatically.
Here's some adapter code:
#NonNull
#Override
public Object instantiateItem(#NonNull ViewGroup container, int position) {
layoutInflater = LayoutInflater.from(context);
View view = layoutInflater.inflate(R.layout.monthlyspend_item, container, false);
TextView monthlySpendMonth, monthlySpendAmount;
monthlySpendCard = view.findViewById(R.id.monthly_spend_card);
monthlySpendMonth = view.findViewById(R.id.monthly_spend_month);
monthlySpendAmount = view.findViewById(R.id.monthly_spend_amount);
monthlySpendMonth.setText(monthlySpendings.get(position).getMonth());
monthlySpendAmount.setText(monthlySpendings.get(position).getAmountSpent());
container.addView(view, 0);
return view;
}
Any help would be appreciated!
I thing you are missing click listener :
view.setOnClickListener(new OnClickListener(){
public void onClick(View v){
// do you stuff here
}
});
((ViewPager)container).addView(view, 0)
Also inside instantiateItem() make int position as final.
you should change your model (in your case "monthlyspendings") at the selected item position.
then notify the adapter
adapter.notifyDataSetChanged()
and finally, custom selected view according to the model. for exapmle :
if(monthlySpendings.get(position).isSelected) monthlySpendCard.setBackgroundColor(Color.parseColor("#fcd14b"));

Dynamically Created Layout not Showing

I've looked at this question here, however I still cannot find out what I'm doing wrong. There are no errors in Logcat and there definitely is data being passed to it to be made. Here's my setup:
This is all taking place below manually placed elements that I have placed in Android Studio. I have a ScrollView. Inside that ScrollView, I have a LinearLayout, parentLayout, that get's passed to this class. This method is supposed to add another Horizontal LinearLayout, layout, parentLayout. Then it is supposed to add a TextView, titleDisplay, and two Buttons to layout. So far I have only programmed just layout and titleDisplay. I tested it, and nothing was added. So before I program the other two buttons, I would like to know what I am doing wrong. Here's the Java Code:
public class FollowupOption {
private String displayName;
private JSONObject jsonInformation;
private Context context;
private LinearLayout parentLayout;
private LinearLayout layout;
private TextView titleDisplay;
private Button deleteButton, editButton;
public FollowupOption(String displayName, JSONObject jsonInformation,
Context context, LinearLayout parentLayout){
this.displayName = displayName;
this.jsonInformation = jsonInformation;
this.context = context;
this.parentLayout = parentLayout;
buildLayout();
}
private void buildLayout(){
//Horizontal Linear Layout to hold everything
this.layout = new LinearLayout(context);
this.layout.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
this.layout.setOrientation(LinearLayout.HORIZONTAL);
this.parentLayout.addView(this.layout);
//Text View Displaying title of followup option.
this.titleDisplay = new TextView(context);
try {
this.titleDisplay.setText(this.jsonInformation.getJSONObject("list").getString("title"));
} catch(JSONException e){ e.printStackTrace(); }
this.titleDisplay.setTextColor(0x8f142a); //Black
this.titleDisplay.setTextSize(18);
this.titleDisplay.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT, 1f));
this.layout.addView(this.titleDisplay);
}
}
Here's my XML:
<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android">
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/parent"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:paddingTop="10dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="38dp"
android:orientation="horizontal">
<TextView
android:id="#+id/textView15"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_weight="0.22"
android:gravity="center"
android:text="#string/followup_text"
android:textColor="#color/myRed"
android:textSize="18sp" />
<Button
android:id="#+id/followup_add_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#android:color/transparent"
android:text="#string/plus"
android:textAlignment="center"
android:textColor="#android:color/holo_green_dark"
android:textSize="30sp"
android:textStyle="bold" />
</LinearLayout>
<ScrollView
android:layout_width="match_parent"
android:layout_height="279dp"
android:paddingLeft="7dp"
android:paddingRight="7dp"
android:paddingTop="7dp">
<LinearLayout
android:id="#+id/followup_parent"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
</LinearLayout>
</ScrollView>
<Button
android:id="#+id/followup_new_button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="#string/new_followup_text" />
</LinearLayout>
</merge>
If someone could let me know what I am doing wrong or a good way to debug something like this, that would be appreciated.
Are you adding this.layout view to some view?
UPD: The problem is with your text color. Consider using the Color class to get color from its hex value or constants from that class.
Does your XML view (without the addition of the dynamic layout) take up the entire screen?
The new LinearLayout view will be added below the button. If the button is at the bottom of the screen, the layout will be added off the screen and therefore not visible.
You should add your new layout to the scroll view instead.

Spinner's background image appears stretched

I have created a dropdown spinner with a background custom image. I have placed the spinner in a linear layout and I have aligned items using weight.
Here is my code -
XML -
<LinearLayout
android:id="#+id/csbar"
android:windowSoftInputMode="adjustPan"
android:paddingTop="8dp"
android:paddingBottom="8dp"
android:layout_alignParentBottom="true"
android:layout_width="match_parent"
android:background="#101010"
android:layout_height="wrap_content">
<ImageButton
android:id="#+id/run"
android:layout_width="0dp"
android:layout_height="#dimen/height"
android:layout_weight="1"
android:background="#null"
android:contentDescription="#string/nul"
android:src="#drawable/ic_action_play" />
<ImageButton
android:id="#+id/save"
android:layout_width="0dp"
android:layout_height="#dimen/height"
android:layout_weight="1"
android:background="#null"
android:contentDescription="#string/nul"
android:src="#drawable/ic_action_save" />
<Spinner
android:id="#+id/more"
android:layout_width="0dp"
android:layout_weight="1"
android:background="#drawable/ic_action_sort_by_size"
android:layout_height="#dimen/height"/>
</LinearLayout>
Java -
int firstC = 0;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
/////I have removed rest of the code to make it more legible/////
Spinner more = (Spinner) rootView.findViewById(R.id.more);
ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(getActivity(),
R.array.more, android.R.layout.simple_spinner_item);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
more.setAdapter(adapter);
more.setOnItemSelectedListener(this);
}
#Override
public void onItemSelected(AdapterView<?> parent, View view, int position,
long id) {
((TextView)view).setText(null);
}
Here is the output -
As you can see the sort by size icon (icon on right) appears stretched.
How I want it to look like -
What is wrong with my code? Please help.
The background image takes all the given space - 1/3 of the the LinearLayout width. If you don’t want it to stretch, you could create a drawable layout, e.g. drawable/my_sort_icon:
<?xml version="1.0" encoding="utf-8"?>
<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
android:src="#drawable/ic_action_sort_by_size"
android:tileMode="disabled"
android:gravity="center" />
and use it as a background image in your Spinner:
<Spinner
android:id="#+id/more"
android:layout_width="0dp"
android:layout_weight="1"
android:background="#drawable/my_sort_icon"
android:layout_height="#dimen/height"/>

How to set OnClickListener for ScrollView?

i'm developing an android project which it has a viewpager. i wrote an adapter for my viewpager and my adapter consist of s scrollview and some views inside that.
i want when user click on the scrollview, something happen (i wrote this part too and test it and it works).
i implement onClickListener for my scrollview but it's not triggered when user click on that.
i have already read this but it's not work for me.
my code for onClickListener is here
rootView = inflater.inflate(R.layout.level_selector_list_view_adapter, container, false);
ScrollView scroll = (ScrollView) rootView.findViewById(R.id.level_selector_view_scroll_view);
scroll.setOnClickListener(new OnClickListener()
{
#Override
public void onClick(View arg0)
{
Log.e(MainActivity.WATERMELON_TAG, "Click!!!");
}
});
and my layout code is this:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="#dimen/level_selector_values_main_page_view_pager_width"
android:layout_height="wrap_content"
android:orientation="vertical" >
<ScrollView
android:id="#+id/level_selector_view_scroll_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clickable="true"
tools:ignore="UselessParent" >
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clickable="false"
tools:ignore="UselessParent" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
android:clickable="false"
android:orientation="vertical" >
<ImageView
android:id="#+id/level_selector_view_pager_adapter_level_logo"
android:layout_width="#dimen/level_selector_values_view_pager_adapter_level_logo_width"
android:layout_height="#dimen/level_selector_values_view_pager_adapter_level_logo_height"
android:layout_gravity="center_horizontal"
android:layout_marginTop="#dimen/level_selector_values_view_pager_adapter_level_logo_top_margin"
android:clickable="false"
android:scaleType="fitXY"
tools:ignore="ContentDescription" />
<TextView
android:id="#+id/level_selector_view_pager_adapter_level_name"
android:layout_width="#dimen/level_selector_values_view_pager_adapter_level_name_width"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginTop="#dimen/level_selector_values_view_pager_adapter_level_name_top_margin"
android:clickable="false"
android:gravity="center"
android:textColor="#color/level_selector_values_level_name_font_color"
android:textSize="#dimen/level_selector_values_level_name_font_size" />
<TextView
android:id="#+id/level_selector_view_pager_adapter_level_score"
android:layout_width="#dimen/level_selector_values_view_pager_adapter_level_score_width"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginTop="#dimen/level_selector_values_view_pager_adapter_level_score_top_margin"
android:clickable="false"
android:gravity="center"
android:textColor="#color/level_selector_values_level_name_font_color"
android:textSize="#dimen/level_selector_values_font_size" />
</LinearLayout>
<ImageView
android:id="#+id/level_selector_view_pager_adapter_lock"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
android:alpha="0.75"
android:clickable="false"
android:scaleType="fitXY"
android:src="#drawable/lock"
tools:ignore="ContentDescription" />
</FrameLayout>
</ScrollView>
The child Views of your ScrollView are consuming the click events you do on the ScrollView.
The solution to this problem is to set the onClickLIstener to the immediate child of the ScrollView, the FrameLayout in your case.
Don't forget to set the layout to "clickable".
Furthermore, I recommend not to use the FrameLayout at all, since it is just a useless container. Instead, just let the LinearLayout that is currently the child of the FrameLayout be the next child to the ScrollView.
try:
public class ClassName implements OnClickListener {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View root = inflater.inflate(R.layout.fragment_child, container, false);
ScrollView scrollView= (ScrollView) root.findViewById(R.id.my_ScrollView);
scrollView.setOnClickListener(this);
return root;
}
#Override
public void onClick(View v) {
Log.e(MainActivity.WATERMELON_TAG, "Click!!!");
}
}

How can I implement a ListView within a LinearLayout?

I am trying to make a simple Checkbook app, whose MainActivity stores a list of transactions. I would like a TextView at the top and bottom of the screen that show the account balance and an option to add a new transaction, respectively. I would like a list of transactions in between that scroll. I was able to implement a ListView and add a header and footer view, but if the transaction list exceeds the size of the screen the headers and footers can scroll off screen.
Is there any way to position a ListView within the linear layout, or freeze the headers/footers to stay on the screen?
Here is my XML file so far:
<TextView
android:id="#+id/header_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:text="#string/default_header_string">
</TextView>
<ListView
android:id="#+id/transaction_list_view"
android:layout_width="match_parent"
android:layout_height="wrap_content">
</ListView>
<TextView
android:id="#+id/footer_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:text="#string/add_transaction_string">
</TextView>
And here is my onCreate, which has no syntax errors but I am unable to click the footerview to add a transaction:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_checkbook);
ListView list = (ListView) findViewById(R.id.transaction_list_view);
// Create a new Adapter
mAdapter = new TransactionAdapter(list.getContext());
// Inflate footerView and headerView
LayoutInflater inflater = getLayoutInflater();
TextView headerView = (TextView) inflater.inflate(R.layout.header_view, null);
TextView footerView = (TextView) inflater.inflate(R.layout.footer_view, null);
// Set listener for footerView
footerView.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View view) {
Intent transactionIntent = new Intent(CheckbookActivity.this, AddTransactionActivity.class);
startActivityForResult(transactionIntent, ADD_TRANSACTION_REQUEST);
}
});
list.setAdapter(mAdapter);
}
use the below code. This will satisfy your requirement. I tried this and working for me.
Relative layout with below,above attributes. Relativelayout is better than Linear layout with weight method.
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/relative"
android:layout_width="match_parent"
android:orientation="vertical"
android:layout_height="match_parent" >
<TextView
android:id="#+id/textView1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_alignParentTop="true"
android:gravity="center_horizontal"
android:text="ListView Heading" />
<TextView
android:id="#+id/textView2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_alignParentBottom="true"
android:gravity="center_horizontal"
android:text="ListView Footer" />
<ListView
android:id="#+id/listView1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#id/textView1"
android:layout_above="#id/textView2"
></ListView>
The UI will like this
Try this way, hope this will help you to solve your problem.
Instead of using header/footer just put as below code in your XML:
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:gravity="center">
<TextView
android:id="#+id/header_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/default_header_string">
</TextView>
<ListView
android:id="#+id/transaction_list_view"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1">
</ListView>
<TextView
android:id="#+id/footer_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/add_transaction_string">
</TextView>
</LinearLayout>
Yes, you can do it with weightsum and layout_weight in linearlayout and also you can create this type of view using RelativeLayout.
1) In LinearLayout just add weightsum="1" to your linearlayout and add layout_weight="0.2" to each of your header and footer and add layout_weight="0.6" to your listview.
2) In relativeLayout add alignParentTop to your header and alignParentBottom to your footer and set listview to layout_below="#+id/header" and layout_above="2+id/footer"
I found a possible solution for your problem from a similiar post. Hope this helps you.
For what you are trying to accomplish to freeze the header/footer. It will be easier to use a relative layout to position the header/footer then have your listview in the middle
<RelativeLayout ...>
<TextView
android:id="#+id/header_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:gravity="center"
android:text="#string/default_header_string">
</TextView>
<ListView
android:id="#+id/transaction_list_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/header_view"
android:layout_above="#+id/footer_view">
</ListView>
<TextView
android:id="#+id/footer_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:gravity="center"
android:text="#string/add_transaction_string">
</TextView>
</RelativeLayout>
You can use a LinearLayout for this task. But I don't recommend it as it's a bit "hacky".
Get all the elements in a array: Example:- (weatherArray)
Loop through all the elements :-
Example:-
mainLayout = ((LinearLayout)refreshObj.get("mainLayout"));
mainLayout.removeAllViews();
for (int i = 0; i < weatherArray.length(); i++) {
View childView = getLayoutInflater().inflate(R.layout.weather_row4_item, mainLayout,false);
TextView todayTempStatus = (TextView) childView.findViewById(R.id.todayTempStatus);
todayTempStatus.setText("");
}
This is an example without using listview, which we will populate lienarlayout using child view.

Categories