RecyclerView: how to add OnClick () and work onLongClick ()?

I have an onClickListener installed in a CheckBox for a RecyclerView that contains a CardView list. The listener is configured in my ItemHolder , which extends ViewHolder . An initial click on CardView checks the CheckBox and switches the CardView background color from white to red by default. This is working correctly.

I also have onClickListener installed in CardView itself. onClickListener configured in onCreateViewHolder() . Clicking on the CardView button launches a new verbose action for CardView . This is working correctly.

Finally, I tried onLongClickListener to CardView. onLongClickListener configured in onCreateViewHolder (). A long press on CardView is intended to switch the background color to red and start AlertDialog so that the user can confirm that CardView will be removed from the list. This works correctly, but when this code is added to the adapter, then OnClickListerner for CardView CheckBox no longer works. It looks like OnLongClickListner is in conflict with the CheckBox listener. Note. I am doing "return true" in the code of itemHolder onLongClick() . What am I missing here?

Adapter.java

 public MyRecylerAdapter(Context context, ArrayList<ListItem> listItems, ArrayList<ListItem> selectedList) { this.mContext = context; this.mListItems = listItems; this.selectedItemsList = selectedList; } private int selectedPos = -1; ... private class ItemHolder extends RecyclerView.ViewHolder implements View.OnClickListener { private CardView cardView; private CheckBox chkSelected; private ItemHolder(final View itemView) { super(itemView); cardView = (CardView) itemView.findViewById(R.id.singlecard_view1); chkSelected = (CheckBox) itemView.findViewById(R.id.chkSelected); chkSelected.setOnClickListener(this); } public void onClick(View v) { int adapterPos = getAdapterPosition(); if (adapterPos == android.support.v7.widget.RecyclerView.NO_POSITION) return; if (recyclerItemClickListener !=null) { recyclerItemClickListener.onCheckBoxClick(v, adapterPos); } Integer iPos = adapterPos; if (((CheckBox)v).isChecked()) { checkedListItems.add(iPos); } else { checkedListItems.remove(iPos); } } void bind(int position) { if (checkedListItems.contains(position)) { chkSelected.setChecked(true); } else { chkSelected.setChecked(false); } } } @Override public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_contact_item, parent, false); final ItemHolder itemHolder = new ItemHolder(view); itemHolder.itemView.setOnClickListener(new View.OnClickListener() { // Handles the row being clicked. @Override public void onClick(View view) { ListItem adapterItem = MyRecylerAdapter.this.getItem(itemHolder.getAdapterPosition()); if (recyclerItemClickListener != null) { recyclerItemClickListener.onItemClick(itemHolder.itemView, adapterItem); } } }); itemHolder.itemView.setOnLongClickListener(new View.OnLongClickListener() { @Override public boolean onLongClick(View view) { ListItem adapterItem2 = MyRecylerAdapter.this.getItem(itemHolder.getAdapterPosition()); if (recyclerItemClickListener != null) { recyclerItemClickListener.onItemLongClick(itemHolder.itemView, adapterItem2); } int adapterPos2 = itemHolder.getAdapterPosition(); if (adapterPos2 != android.support.v7.widget.RecyclerView.NO_POSITION) { int lastSelectedPosition = selectedPos; selectedPos = adapterPos2; notifyItemChanged(lastSelectedPosition); notifyItemChanged(selectedPos); } return true; } }); return itemHolder; } public void onBindViewHolder(final RecyclerView.ViewHolder holder, int position) { final ListItem listItem = mListItems.get(position); final ItemHolder itemHolder = (ItemHolder) holder; itemHolder.bind(position); if (checkedListItems.contains(position)) { itemHolder.cardView.setActivated(true); } else { itemHolder.cardView.setActivated(false); } // **The addition of the below code causes the "itemHolder.cardView. // setActivated(true);" in onBindViewHolder method to no longer fire, as // a click on the CheckBox no longer changes the CardView background // color.** if (itemHolder.getAdapterPosition() == selectedPos) { itemHolder.cardView.setActivated(true); } else { itemHolder.cardView.setActivated(false); } 

list_contact_item.xml

 <?xml version="1.0" encoding="utf-8"?> <android.support.v7.widget.CardView xmlns:card_view="http://schemas.android.com/apk/res-auto" xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/singlecard_view1" android:layout_width="match_parent" android:layout_height="wrap_content" android:foreground="?android:attr/selectableItemBackground" > <RelativeLayout android:layout_width="match_parent" android:layout_height="match_parent" android:background="@drawable/statelist_cardview_background" > <CheckBox android:id="@+id/chkSelected" android:layout_width="wrap_content" android:layout_height="30dp" android:layout_alignParentTop="true" android:layout_alignParentStart="true" android:layout_alignParentLeft="true" android:layout_marginLeft="4dp" android:layout_marginStart="4dp" android:layout_marginTop="4dp" android:gravity="center" /> <TextView android:id="@+id/cardType1" android:layout_width="wrap_content" android:layout_height="30dp" android:layout_toRightOf="@+id/chkSelected" android:layout_toEndOf="@+id/chkSelected" android:layout_alignParentTop="true" android:paddingStart="3dp" android:paddingLeft="3dp" android:paddingEnd="6dp" android:paddingRight="6dp" android:layout_marginTop="4dp" android:gravity="center" android:textColor="#ffffff" android:textStyle="bold|italic" style="@style/Base.TextAppearance.AppCompat.Subhead" /> <TextView android:id="@+id/cardBlankText1" android:layout_width="wrap_content" android:layout_height="30dp" android:layout_alignParentTop="true" android:layout_toRightOf="@+id/cardType1" android:layout_toEndOf="@+id/cardType1" android:layout_toLeftOf="@+id/cardBlankTextNumstotal" android:layout_toStartOf="@+id/cardBlankTextNumstotal" android:layout_marginTop="4dp" android:gravity="center_vertical|end" android:text="#" android:textColor="@color/colorFlLabelFinal" android:textStyle="bold" android:maxLines="1" style="@style/Base.TextAppearance.AppCompat.Subhead" /> <TextView android:id="@+id/cardBlankTextNumstotal" android:layout_width="wrap_content" android:layout_height="30dp" android:layout_alignParentTop="true" android:layout_alignParentEnd="true" android:layout_alignParentRight="true" android:gravity="center" android:text="actual card #" android:layout_marginTop="4dp" android:layout_marginRight="4dp" android:layout_marginEnd="4dp" android:freezesText="true" android:textColor="@android:color/black" android:maxLines="1" style="@style/Base.TextAppearance.AppCompat.Subhead" /> <TextView android:id="@+id/cardBlankText2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:layout_alignParentStart="true" android:layout_below="@+id/chkSelected" android:layout_marginTop="4dp" android:layout_marginLeft="6dp" android:layout_marginStart="6dp" android:text="todo" android:textColor="@android:color/black" android:textStyle="bold" android:background="@drawable/todo_underline" android:maxLines="1" style="@style/Base.TextAppearance.AppCompat.Headline" /> ... </RelativeLayout> </android.support.v7.widget.CardView> 

statelist_cardview_background.xml

 <?xml version="1.0" encoding="utf-8"?> <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:state_activated="true" android:drawable="@color/item_selected" /> <item android:state_activated="false" android:drawable="@color/list_contact_item_default" /> </selector> 

colors.xml

 <?xml version="1.0" encoding="utf-8"?> <resources> <color name="list_contact_item_default">#FFFFFF</color> <color name="item_selected">#FF0000</color> </resources> 
+7
android checkbox android-recyclerview
Dec 13 '17 at 0:13
source share
5 answers

It seems you are trying to solve the wrong problem here. You should not set clicks and long clicks on the map screen .

  • You can listen to the click OR checkedChangeListener in the checkbox
  • click and long click users may be on vacation view_container

Here, if you want to check / uncheck the box and when you click view_container , you can easily do this in the view_container onClick of the listener.

Edit : I updated your layout file, now you have on the FrameLayout as the parent element of the RelativeLayout (view_container) and checkbox.

When a flag is added after RelativeLayout, it will be visible on top of view_container. Hope this works for you.

You can now install click listeners , as I explained above .

Updated Layout File

 <?xml version="1.0" encoding="utf-8"?> <android.support.v7.widget.CardView xmlns:card_view="http://schemas.android.com/apk/res-auto" xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/singlecard_view1" android:layout_width="match_parent" android:layout_height="wrap_content" android:foreground="?android:attr/selectableItemBackground" > <FrameLayout android:layout_width="match_parent" android:layout_height="match_parent"> <RelativeLayout android:id="@+id/view_container" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@drawable/statelist_cardview_background" > <TextView android:id="@+id/cardType1" android:layout_width="wrap_content" android:layout_height="30dp" android:layout_marginLeft="30dp" android:layout_marginStart="30dp" android:layout_alignParentTop="true" android:paddingStart="3dp" android:paddingLeft="3dp" android:paddingEnd="6dp" android:paddingRight="6dp" android:layout_marginTop="4dp" android:gravity="center" android:textColor="#ffffff" android:textStyle="bold|italic" style="@style/Base.TextAppearance.AppCompat.Subhead" /> <TextView android:id="@+id/cardBlankText1" android:layout_width="wrap_content" android:layout_height="30dp" android:layout_alignParentTop="true" android:layout_toRightOf="@+id/cardType1" android:layout_toEndOf="@+id/cardType1" android:layout_toLeftOf="@+id/cardBlankTextNumstotal" android:layout_toStartOf="@+id/cardBlankTextNumstotal" android:layout_marginTop="4dp" android:gravity="center_vertical|end" android:text="#" android:textColor="@color/colorFlLabelFinal" android:textStyle="bold" android:maxLines="1" style="@style/Base.TextAppearance.AppCompat.Subhead" /> <TextView android:id="@+id/cardBlankTextNumstotal" android:layout_width="wrap_content" android:layout_height="30dp" android:layout_alignParentTop="true" android:layout_alignParentEnd="true" android:layout_alignParentRight="true" android:gravity="center" android:text="actual card #" android:layout_marginTop="4dp" android:layout_marginRight="4dp" android:layout_marginEnd="4dp" android:freezesText="true" android:textColor="@android:color/black" android:maxLines="1" style="@style/Base.TextAppearance.AppCompat.Subhead" /> <TextView android:id="@+id/cardBlankText2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:layout_alignParentStart="true" android:layout_marginTop="34dp" android:layout_marginLeft="6dp" android:layout_marginStart="6dp" android:text="todo" android:textColor="@android:color/black" android:textStyle="bold" android:background="@drawable/todo_underline" android:maxLines="1" style="@style/Base.TextAppearance.AppCompat.Headline" /> ... </RelativeLayout> <CheckBox android:id="@+id/chkSelected" android:layout_width="wrap_content" android:layout_height="30dp" android:layout_alignParentTop="true" android:layout_alignParentStart="true" android:layout_alignParentLeft="true" android:layout_marginLeft="4dp" android:layout_marginStart="4dp" android:layout_marginTop="4dp" android:gravity="center" /> </FrameLayout> </android.support.v7.widget.CardView> 
0
Dec 20 '17 at 20:20
source share

Why don't you use OnCheckedChangeListener for the checkbox?

 CheckBox chkBox = ( CheckBox ) findViewById( R.id.checkbox ); chkBox.setOnCheckedChangeListener(new OnCheckedChangeListener() { @Override public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { if ( isChecked ) { // perform logic } } }); 
+2
Dec 19 '17 at 2:44 on
source share

try it

 public class MyRecylerAdapter extends RecyclerView.Adapter<MyRecylerAdapter.ItemHolder> { ... public MyRecylerAdapter(Context context, ArrayList<ListItem> listItems, ArrayList<ListItem> selectedList) { this.mContext = context; this.mListItems = listItems; this.selectedItemsList = selectedList; } private int selectedPos = -1; public class ItemHolder extends RecyclerView.ViewHolder { private CardView cardView; private CheckBox chkSelected; private ItemHolder(final View itemView) { super(itemView); cardView = (CardView) itemView.findViewById(R.id.singlecard_view1); chkSelected = (CheckBox) itemView.findViewById(R.id.chkSelected); } void bind(int position) { if (checkedListItems.contains(position)) { chkSelected.setChecked(true); } else { chkSelected.setChecked(false); } } } @Override public ItemHolder onCreateViewHolder(ViewGroup parent, int viewType) { View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_contact_item, parent, false); final ItemHolder itemHolder = new ItemHolder(view); return itemHolder; } public void onBindViewHolder(final ItemHolder itemHolder, final int position) { final ListItem listItem = mListItems.get(position); itemHolder.bind(position); if (checkedListItems.contains(position)) { itemHolder.cardView.setActivated(true); } else { itemHolder.cardView.setActivated(false); } if (itemHolder.getAdapterPosition() == selectedPos) { itemHolder.cardView.setActivated(true); } else { itemHolder.cardView.setActivated(false); } itemHolder.itemView.setOnClickListener(new View.OnClickListener() { // Handles the row being clicked. @Override public void onClick(View view) { if (recyclerItemClickListener != null) { recyclerItemClickListener.onItemClick(itemHolder.itemView, listItem); } } }); itemHolder.itemView.setOnLongClickListener(new View.OnLongClickListener() { @Override public boolean onLongClick(View view) { if (recyclerItemClickListener != null) { recyclerItemClickListener.onItemLongClick(itemHolder.itemView, listItem); } int adapterPos2 = itemHolder.getAdapterPosition(); if (adapterPos2 != android.support.v7.widget.RecyclerView.NO_POSITION) { int lastSelectedPosition = selectedPos; selectedPos = adapterPos2; notifyItemChanged(lastSelectedPosition); notifyItemChanged(selectedPos); } return true; } }); itemHolder.chkSelected.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if (position == android.support.v7.widget.RecyclerView.NO_POSITION) return; if (recyclerItemClickListener != null) { recyclerItemClickListener.onCheckBoxClick(v, position); } Integer iPos = position; if (((CheckBox) v).isChecked()) { checkedListItems.add(iPos); } else { checkedListItems.remove(iPos); } } }); } @Override public int getItemCount() { return mListItems.size(); } } 
0
Dec 15 '17 at 6:26
source share

If I understand your question correctly, try this code and let me know if it does not work.

Java Code Adapter

 public class Adapter extends RecyclerView.Adapter<Adapter.ItemHolder> { private ArrayList<DemoData> mDemoData; public Adapter() { mDemoData = new ArrayList<>(); for (int i = 0; i <= 100; i++) { mDemoData.add(new DemoData("Item " + i, false)); } } @Override public ItemHolder onCreateViewHolder(ViewGroup parent, int viewType) { return new ItemHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.recyler_card, parent, false)); } @Override public void onBindViewHolder(ItemHolder holder, int position) { //Check if the item is check and toggle the checkbox if (mDemoData.get(position).checked) { holder.mCheckBox.setChecked(true); } else { holder.mCheckBox.setChecked(false); } //Set text to the textview holder.mTextView.setText(mDemoData.get(position).item); } @Override public int getItemCount() { return mDemoData.size(); } public class ItemHolder extends RecyclerView.ViewHolder { private TextView mTextView; private CheckBox mCheckBox; public ItemHolder(View itemView) { super(itemView); mTextView = (TextView) itemView.findViewById(R.id.textView); mCheckBox = (CheckBox) itemView.findViewById(R.id.checkbox); //set OnClickListener itemView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Toast.makeText(mCheckBox.getContext(), "Clicked", Toast.LENGTH_SHORT).show(); } }); //set OnLongClickListener itemView.setOnLongClickListener(new View.OnLongClickListener() { @Override public boolean onLongClick(View v) { //if handled return true if not return false; Toast.makeText(mCheckBox.getContext(), "Long Clicked", Toast.LENGTH_SHORT).show(); return false; } }); mCheckBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { @Override public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { mDemoData.get(getAdapterPosition()).checked = isChecked; } }); } } } 

ItemView XML

 <?xml version="1.0" encoding="utf-8"?> <android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="75dp"> <LinearLayout android:layout_width="match_parent" android:layout_height="75dp" android:orientation="horizontal"> <TextView android:id="@+id/textView" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <CheckBox android:id="@+id/checkbox" android:layout_width="wrap_content" android:layout_height="wrap_content" /> </LinearLayout> </android.support.v7.widget.CardView> 

Java activity

 public class RecyclerDemoActivity extends AppCompatActivity { private RecyclerView mRecyclerView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_recycler_demo); mRecyclerView = (RecyclerView) findViewById(R.id.recyclerView); mRecyclerView.setLayoutManager(new LinearLayoutManager(getApplicationContext())); mRecyclerView.setAdapter(new Adapter()); } } 

Just use this demo and modify your code accordingly.

Edit: This is the model class that is used.

  public class DemoData{ public String item; public boolean checked; public DemoData(String item,boolean isChecked){ this.item=item; this.checked=isChecked; } } 

| REY |

0
Dec 18 '17 at 10:52
source share

you must provide you with the data (mListItems), add isChecked Fileds !, and you can do it

 holder.checkebox.setchecked(false); if(mListItems.get(position).ischekced){ holder.checkebox.setchecked(true); } holder.checkebox..setOnCheckedChangeListener(new OnCheckedChangeListener(){ @Override public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { mListItems.get(position).isChecked=isChecked; } }); 
0
Dec 21 '17 at 2:44 on
source share



All Articles