I am working on an Android app. I am facing some problem with opening a popup menu when I click on an Item in the Recycler View.
Show.java (the Activity containing the Recycler View). mRecycler is the object associated with the RecyclerView.
mRecycler.addOnItemTouchListener(new RecyclerTouchListener(getApplicationContext(), mRecycler, new RecyclerViewClickListener() {
#Override
public void onClick(View view, final int position) {
PopupMenu menu = new PopupMenu(Show.this,mRecycler);
MenuItem itemView = (MenuItem) findViewById(R.id.three);
if(method.equals("Completed"))
itemView.setTitle("Mark as imcomplete");
menu.getMenuInflater().inflate(R.menu.menu_popup,menu.getMenu());
menu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener(){
public boolean onMenuItemClick(MenuItem item){
int id=item.getItemId();
switch (id){
case R.id.one:
Intent intent = new Intent(Show.this,Add.class);
intent.putExtra("Task",tasks.get(position));
startActivity(intent);
finish();
startActivity(getIntent());
break;
case R.id.two:
deleteRecord(position);
break;
case R.id.three:
toggleComplete(position);
}
return true;
}
});
}
#Override
public void onLongClick(View view, int position) {
onClick(view,position);
}
}));
Code snippet for xml of RecyclerView
<android.support.v7.widget.RecyclerView
android:id="#+id/recycler"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:scrollbars="vertical"
android:clickable="true"
android:contextClickable="true"
android:longClickable="true" />
RecyclerViewClickListener.java
public interface RecyclerViewClickListener {
void onClick(View view,int position);
void onLongClick(View view,int position);
}
RecyclerTouchListener.java - class that implements the OnItemTouchListener
public class RecyclerTouchListener implements RecyclerView.OnItemTouchListener{
private GestureDetector gestureDetector;
private RecyclerViewClickListener clickListener;
public RecyclerTouchListener (Context context,final RecyclerView recyclerView,
final RecyclerViewClickListener clickListener){
this.clickListener = clickListener;
gestureDetector = new GestureDetector(context,new GestureDetector.SimpleOnGestureListener(){
#Override
public boolean onSingleTapUp(MotionEvent e){
return true;
}
#Override
public void onLongPress(MotionEvent e){
View child = recyclerView.findChildViewUnder(e.getX(),e.getY());
if (child != null && clickListener!=null)
clickListener.onLongClick(child,recyclerView.getChildAdapterPosition(child));
}
});
}
#Override
public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e){
View child = rv.findChildViewUnder(e.getX(),e.getY());
if (child !=null && clickListener !=null && gestureDetector.onTouchEvent(e))
clickListener.onClick(child,rv.getChildAdapterPosition(child));
return false;
}
#Override
public void onTouchEvent(RecyclerView rv,MotionEvent e){}
#Override
public void onRequestDisallowInterceptTouchEvent(boolean disallowIntecept){}
}
Nothing happens when I click an item on the RecyclerView. The android system does not even acknowledge that it was clicked. Please check what is the problem with my code.
Would You please try this
mRecyclerView.addOnItemTouchListener(new RecyclerTouchListener(getApplicationContext(), mRecyclerView, new ClickListener() {
#Override
public void onClick(View view, int position) {
menuCardIndex = position;
PopupMenu popupMenu = new PopupMenu(Show.this, view);
popupMenu.setOnMenuItemClickListener(Show.this);
popupMenu.inflate(R.menu.menu_popup);
popupMenu.show();
}
#Override
public void onLongClick(View view, int position) {
}
}));
#Override
public boolean onMenuItemClick(MenuItem item) {
switch (item.getItemId()) {
case R.id.one:
Your_First_Operation;
return true;
case R.id.two:
Your_Second_Operation;
return true
case R.id.three:
Your_Third_Operation;
return true
}
return false;
}
finally put this one your activity
public class Show extends AppCompactActivity implements PopupMenu.OnMenuItemClickListener
hopefully by this way, You can listen your click listener. if it's working properly, You can set your logic.
If your RecyclerView items have "clickable" children in their XML file, try to declare the property:
android:clickable="false"
Leave the clickable true only on the father of your list item.
If this is not your case, or you absolutely need clickable elements in your list item, there is another solution.
If you are using a RecyclerView, you should have implementend a RecyclerView Adapter somewhere in your code.
In the OnBindViewHolder method, try the following code:
#Override
public void onBindViewHolder(final ViewHolder holder, int position) {
//YOUR CODE ...
holder.itemView.setOnTouchListener(yourOnTouchListener);
//MORE CODE ...
}
This will set the OnTouchListener to the single ItemView at the moment the list is generated.
I hope my answer is helpful and understandable enough.
Related
I have menu option in Recyclerview item row when user clicks on that row element then I want to show pop menu. I have implemented this functionality and on click message is showing on log but popmenu is not showing up.
Below is my code:
public class PdfAdapter extends RecyclerView.Adapter<PdfAdapter.ViewHolder> {
Context context;
List<Pdfs> pdfList;
public PdfAdapter(Context context, List<Pdfs> pdfList) {
this.context = context;
this.pdfList = pdfList;
}
#NonNull
#Override
public ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.pdf_item_row,parent,false);
return new ViewHolder(v);
}
#Override
public void onBindViewHolder(#NonNull ViewHolder holder, int position) {
Pdfs model = pdfList.get(position);
holder.pdfName.setText(model.getFilenamename());
holder.datTime.setText(model.getDatetime());
holder.menu.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Log.d("clik","Hello");
PopupMenu popupMenu = new PopupMenu(context,holder.menu);
popupMenu.inflate(R.menu.row_menu);
popupMenu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
#Override
public boolean onMenuItemClick(MenuItem item) {
switch (item.getItemId()) {
case R.id.itemShare:
break;
case R.id.itemDel:
break;
case R.id.itemDownload:
Toast.makeText(context,model.getFileurl(),Toast.LENGTH_SHORT).show();
break;
}
return false;
}
});
}
});
}
#Override
public int getItemCount() {
return pdfList.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
TextView pdfName,menu,datTime;
public ViewHolder(#NonNull View itemView) {
super(itemView);
pdfName = itemView.findViewById(R.id.pdfName);
menu = itemView.findViewById(R.id.menu);
datTime = itemView.findViewById(R.id.datTime);
}
}
}
What am I doing wrong?
You forgot to call .show() method on popupMenu.
Add below line at last inside click listener.
popupMenu.show();
I have created an interface with three functions click, like, and delete. I am trying to figure out the best way to approach the like method and how to implement it. Any suggestions? Would I have to make a database reference in Firebase to store likes etc. or can I do it in the device's local memory? Any help would be great. Below is my Adapter & snippet of my MainActivity where I am attempting to place all the like code.
public class ImageAdapter extends RecyclerView.Adapter<ImageAdapter.ImageViewHolder>{
private Context context;
private List<Upload> uploads;// a list containing content from Uploads class to do this we need constructor
private OnItemClickListener Listener;
public ImageAdapter(Context context, List<Upload> uploads) {
this.context = context;
this.uploads = uploads;
}
#NonNull
#Override
public ImageViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {//pass in layout of cards to populate uploads
View v = LayoutInflater.from(context).inflate(R.layout.image_item, parent, false);
return new ImageViewHolder(v);
}
#Override
public void onBindViewHolder(#NonNull ImageViewHolder holder, int position) {//get data out of our uploads
Upload upload = uploads.get(position);
}
#Override
public int getItemCount() {
return uploads.size();
}
public class ImageViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener,
View.OnCreateContextMenuListener, MenuItem.OnMenuItemClickListener {
public ImageViewHolder(#NonNull View itemView) {
super(itemView);
//ImageViewHolder will now handle click events within its constructor
itemView.setOnClickListener(this);
itemView.setOnCreateContextMenuListener(this);
}
#Override
public void onClick(View v) {//we can now handle click events on our itemView using this constructor and we want to pass
//these clicks back over its interface with position.
if (Listener != null){
int position = getAdapterPosition();//grabs position of the clicked item
if (position != RecyclerView.NO_POSITION);{//this makes sure the click position is still valid
Listener.onItemClick(position);
}
}
}
#Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
menu.setHeaderTitle("Select Action");
MenuItem like = menu.add(Menu.NONE, 1, 1, "Like");
MenuItem delete = menu.add(Menu.NONE, 2, 2, "Delete");
like.setOnMenuItemClickListener(this);
delete.setOnMenuItemClickListener(this);
}
#Override
public boolean onMenuItemClick(MenuItem item) {
if (Listener != null){
int position = getAdapterPosition();
if (position != RecyclerView.NO_POSITION);{
switch (item.getItemId()){
case 1:
Listener.onLikeClick(position);
return true;
case 2:
Listener.onDeleteClick(position);
return true;
}
}
}
return false;
}
}
//implement LikeClick in mainactivity page
public interface OnItemClickListener{
void onItemClick(int position);//handles general clicks
void onLikeClick(int position);//handles like clicks
void onDeleteClick(int position);//handles delete clicks
}
public void setOnItemClickListener(OnItemClickListener listener){//we have set the activity as a listener for our interface
Listener = listener;
}
}
//this method is used to set activity for our interface
//Listener = listener sets activity as the Listener for interface
#Override
public void onLikeClick(int position) {
Toast.makeText(this,"Like" + position, Toast.LENGTH_SHORT).show();
}
//within this function edit it to start generating likes.
You can implement the inteface in your main activity and on click to call other method to update the likes etc. and about saving you could go both ways depending on the app you are building.
I have a RecyclerView in my activity and I want to add Multiple selection to the RecyclerView, and this is my Adapter:
public class RingtoneItemAdabter extends RecyclerView.Adapter<RingtoneItemAdabter.ViewHolder> {
private Context context;
private Activity activity;
private List<RingtoneItem> list;
private boolean selectionMode = false;
private List<RingtoneItem> selectedItems = new ArrayList<>();
public class ViewHolder extends RecyclerView.ViewHolder {
public Switch aSwitch;
public TextView textView;
public View view;
public CheckBox checkBox;
public ViewHolder(View view) {
super(view);
this.view = view;
aSwitch = (Switch) view.findViewById(R.id.ringtone_state_switch);
textView = (TextView) view.findViewById(R.id.ringtone_title_textview);
checkBox = (CheckBox) view.findViewById(R.id.selection_checkbox);
}
}
public RingtoneItemAdabter(Context context, Activity activity, List<RingtoneItem> list) {
this.context = context;
this.activity = activity;
this.list = list;
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
LayoutInflater inflater = LayoutInflater.from(context);
View view = inflater.inflate(R.layout.recyclerview_item, parent, false);
ViewHolder viewHolder = new ViewHolder(view);
return viewHolder;
}
#Override
public void onBindViewHolder(final ViewHolder holder, int position) {
final RingtoneItem item = list.get(position);
holder.checkBox.setVisibility(selectionMode ? View.VISIBLE : View.GONE);
holder.textView.setText(item.getTitle());
holder.aSwitch.setChecked(item.isActive());
holder.textView.setTextColor(item.isActive() ? Color.BLACK : Color.GRAY);
holder.aSwitch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if (isChecked) {
holder.textView.setTextColor(Color.BLACK);
item.setActive(true);
writeToFile();
} else {
holder.textView.setTextColor(Color.GRAY);
item.setActive(false);
writeToFile();
}
}
});
holder.view.setOnLongClickListener(new View.OnLongClickListener() {
#Override
public boolean onLongClick(View v) {
if(selectionMode){
return false;
}else {
startSelecting();
holder.checkBox.setChecked(true);
return true;
}
}
});
holder.view.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(selectionMode){
holder.checkBox.setChecked(!holder.checkBox.isChecked());
}
}
});
holder.checkBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if(isChecked){
selectedItems.add(item);
}else {
selectedItems.remove(item);
}
if(selectedItems.size() == 0){
stopSelecting();
}
}
});
}
#Override
public int getItemCount() { ... }
private void writeToFile() { ... }
private void startSelecting(){
selectionMode = true;
notifyDataSetChanged();
}
private void stopSelecting(){
selectionMode = false;
notifyDataSetChanged();
}
}
and this is the checkbox tag in recyclerview_item:
<CheckBox
android:id="#+id/selection_checkbox"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="4dp"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent" />
so I want the startSelection method to show the checkbox in every item, and the stopSelection method to hide the checkbox in every item.
EDIT:
It's looks like I got a problem, the problem is now when I click and hold on an item the checkboxes appear and the checkbox of the item I long clicked must get checked, and if I unchecked every box, the checkboxed should disappear,this is how the app should work, but the when I tried it, it's didn't work, when I long click an item the checkboxes appear in some cases another checkbox get checked, but in another cases no one of the checkboxes get checked, and when I uncheck every checkbox, the checkboxes stay there.
I have an idea about why the checkboxed don't disappear, because for example if I long clicked the fourth item, the checkboxes will appear, but rather than the fourth item which should get checked the first item will get checked, but the fourth item is the one which will added to selectedItems list, so if I unchecked the first box nothing will happen because it's not stored in the list, but if I checked the fourth item, then another fourth item will added to the list, and if I unchecked it, one of the two copies of the fourth item will removed, but one will stay.
check the code above.
I know my explain is very bad, and my English isn't very good, but hope you understand :)
Define a boolean variable for show/hide checkbox state and in onBindViewHolder set visibility of your checkbox related to that variable
boolean showCheckboxes = false;
public void startSelection() {
showCheckboxes = true;
notifyDataSetChanged();
}
public void stopSelection() {
showCheckboxes = false;
notifyDataSetChanged();
}
#Override
public void onBindViewHolder(final ViewHolder holder, int position) {
final RingtoneItem item = list.get(position);
holder.checkBox.setVisibility(showCheckboxes ? View.VISIBLE: View.GONE);
/*
...
*/
}
I am using recyclerView to build a list of toggle buttons (like a numpad), I would like to achieve:
when user 'turns on' a button by clicking it, 'turns off' all other buttons
I have tried to add an onClickListener inside the view holder class, and call notifyDataSetChanged() such that onBindViewHolder(final ViewHolder holder, int position) is called and then change the state of the button.
But it doesn't work, the button clicked does not change its state.
ViewHolder
class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener{
ToggleButton button;
String id;
public ViewHolder(View itemView) {
super(itemView);
button = (ToggleButton) itemView.findViewById(R.id.toggle);
button.setOnclickListener(this);
}
#Override
public void onClick(View view) {
((ToggleButton) view).setChecked(true);
int pos = getAdapterPosition();
if (pos != RecyclerView.NO_POSITION) {
selected = pos; //store the position of the user clicked button
notifyDataSetChanged();
}
}
onBindViewHolder() in my adpater class
public void onBindViewHolder(final ViewHolder holder, int position) {
String data = mData.get(position);
holder.id = data;
holder.button.setText(data);
holder.button.setTextOn(data);
holder.button.setTextOff(data);
if (position != selected) { //if the button is not the user chosen one
if (holder.button.isChecked()) { // and it's in 'ON' state
holder.button.toggle(); // toggle it to switch 'OFF'
}
}
There are a couple of things you are doing incorrectly. The ViewHolder should contain only views and not click handlers or strings etc. (The clue is in the name). You add the handlers and manipulate the views when you bind the ViewHolder to your data class.
From what I can determine, you want a simple list of toggle buttons. When one button is on, the others should turn off. The test adapter I created for you below demonstrates that.
Ideally, you would avoid notifyDataSetChanged and use the row based versions but as each time the toggle is pressed, it affects every other row, you do not really have a choice in this use case unless you keep track of the selected row.
public class TestAdapter extends RecyclerView.Adapter<TestAdapter.VH> {
public static class MyData {
public boolean Selected = false;
public String Text;
public MyData(String text) {
Text = text;
}
}
public List<MyData> items = new ArrayList<>();
public TestAdapter() {
this.items.add(new MyData("Item 1"));
this.items.add(new MyData("Item 2"));
this.items.add(new MyData("Item 3"));
}
#Override
public TestAdapter.VH onCreateViewHolder(ViewGroup parent, int viewType) {
return new VH((
LayoutInflater.from(parent.getContext())
.inflate(R.layout.test_layout, parent, false))
);
}
#Override
public void onBindViewHolder(TestAdapter.VH holder, int position) {
final MyData itm = items.get(position);
holder.button.setChecked(itm.Selected);
holder.text.setText(itm.Text);
holder.button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
for (MyData x: items){
x.Selected=false;
}
itm.Selected = true;
notifyDataSetChanged();
}
});
}
#Override
public int getItemCount() {
return items.size();
}
public class VH extends RecyclerView.ViewHolder {
ToggleButton button;
TextView text;
public VH(View itemView) {
super(itemView);
button = itemView.findViewById(R.id.toggle);
text = itemView.findViewById(R.id.text1);
}
}
}
test_layout.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<ToggleButton
android:id="#+id/toggle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<TextView
android:id="#+id/text1"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</LinearLayout>
Try setting OnCheckedChangeListener instead of 'OnclickListener`
`button.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if (isChecked) {
// The toggle is enabled
} else {
// The toggle is disabled
}
}
});`
Android Doc : https://developer.android.com/guide/topics/ui/controls/togglebutton.html
set on click listener in the onBindView and In the onClick method,
first "turn off" all the toggle button by setting a parameter in the list model
and then "turn on" the selected one if it is not selected.
#Override
public void onClick(View view) {
// clear all model values to isSelected false in the list
}
I had the following holder that worked, i.e. I was able to check/uncheck the checkbox. (The checkbox is part of the RecyclerView card):
#Override
public void onBindViewHolder(final ViewHolder holder, int position) {
holder.bindData(numbers.get(position));
//in some cases, it will prevent unwanted situations
holder.checkbox.setOnCheckedChangeListener(null);
//if true, your checkbox will be selected, else unselected
holder.checkbox.setChecked(numbers.get(position).isSelected());
holder.checkbox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
numbers.get(holder.getAdapterPosition()).setSelected(isChecked);
}
});
}
I wanted to implement click of the item on RecyclerView. So, I took from this solution - please check: https://stackoverflow.com/a/26196831/4013399
However, now, the click of the entire card item works, but the checkbox can not be checked/unchecked. How to solve this?
Please help. Thanks.
Update
I made changes - however, "HERE-1,2 and 3" lines are never entered.
#Override
public void onBindViewHolder(final ViewHolder holder, int position) {
Log.e("I AM ", "HERE-0");
holder.bindData(numbers.get(position));
final RelativeLayout rlyItem = holder.rlyItem;
final CheckBox checkbox = holder.checkbox;
rlyItem.setOnClickListener(new View.OnClickListener() {
#Override public void onClick(View view) {
mListener.onItemClicked(holder.getLayoutPosition());
Log.e("I AM ", "HERE-1");
}
});
checkbox.setOnClickListener(new View.OnClickListener() {
#Override public void onClick(View view) {
if (((CheckBox) view).isChecked()) {
checkbox.setChecked(false);
Log.e("I AM ", "HERE-2");
} else {
checkbox.setChecked(true);
Log.e("I AM ", "HERE-3");
}
// Inform to Activity or the Fragment where the RecyclerView reside.
mListener.onItemCheckBoxChecked(((CheckBox) view).isChecked(), holder.getLayoutPosition());
}
});
//in some cases, it will prevent unwanted situations
holder.checkbox.setOnCheckedChangeListener(null);
//if true, your checkbox will be selected, else unselected
holder.checkbox.setChecked(numbers.get(position).isSelected());
checkbox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
numbers.get(holder.getAdapterPosition()).setSelected(isChecked);
Log.e("I AM ", "HERE-4");
//Log.e(Integer.toString(holder.getAdapterPosition()), " IS CHECKED");
}
});
}
Simply call performClick() for your checkbox on click of your adapter inflated view in adapter class.
holder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
holder.checkbox.performClick();
}
});
First You add the below property in your checkbox
android:clickable="false"
android:focusable="false"
android:longClickable="false"
Below is my itemclick
recyclerView.addOnItemTouchListener(new RecyclerItemClickListener(getActivity(), new RecyclerItemClickListener.OnItemClickListener() {
#Override
public void onItemClick(View view, int position) {
Utils.hideSoftKeyboard(getActivity());
cityAdapter.itemSelected(position);
}
}));
Add below method in your adapter :
public void itemSelected(final int position) {
if (townModelArrayList != null && !townModelArrayList.isEmpty()) {
townModelArrayList.get(position).setSelected(!townModelArrayList.get(position).isSelected());
notifyDataSetChanged();
}
}
I wrote a library to handle android recycler view item click event. You can find whole tutorial in https://github.com/ChathuraHettiarachchi/RecycleClick
RecycleClick.addTo(YOUR_RECYCLEVIEW).setOnItemClickListener(new RecycleClick.OnItemClickListener() {
#Override
public void onItemClicked(RecyclerView recyclerView, int position, View v) {
// YOUR CODE
}
});
or to handle item long press you can use
RecycleClick.addTo(YOUR_RECYCLEVIEW).setOnItemLongClickListener(new RecycleClick.OnItemLongClickListener() {
#Override
public boolean onItemLongClicked(RecyclerView recyclerView, int position, View v) {
// YOUR CODE
return true;
}
});
to handle checkbox click you need to setCheckChangeListner on your adapter
I solved this problem by removing the whole class referenced in the question link (https://stackoverflow.com/a/26196831/4013399). Instead I implemented an onClick listener only for the checkbox. And for the whole card view item click?, you may ask. For that, I simply implemented another onClick listener for a layout that contained my textbox.
Also, to save the state of the checkboxes a simple setting and getting of key,value pairs like (checkbox position, "1") (where 1 indicates checked) and simultaneously updating this in the SharedPreferences worked.
TL; DR
To implement RecyclerView item click and a clickable view in RecyclerView item, You need to define listener for each of them.
First, you need to define the layout:
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
>
<RelativeLayout
android:id="#+id/item__rly"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?android:selectableItemBackground"
android:clickable="true"
>
<CheckBox
android:id="#+id/item_cbx"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Sample CheckBox" />
</RelativeLayout>
</android.support.v7.widget.CardView>
From the above xml code, you can find that the RelativeLayout using:
android:background="?android:selectableItemBackground"
android:clickable="true"
This is to make the item having an animation when clicked.
Second, you need to define click listener interface within your Adapter, something like this:
public class YourAdapter extends
RecyclerView.Adapter<YourAdapter.ViewHolder> {
private List<YourData> mDatas;
// Define listener member variable
private static OnRecyclerViewItemClickListener mListener;
// Define the listener interface
public interface OnRecyclerViewItemClickListener {
void onItemClicked(int position);
void onItemCheckBoxChecked(boolean isChecked, int position);
}
// Define the method that allows the parent activity or fragment to define the listener.
public void setOnRecyclerViewItemClickListener(OnRecyclerViewItemClickListener listener) {
this.mListener = listener;
}
public static class ViewHolder extends RecyclerView.ViewHolder {
RelativeLayout rlyItem;
CheckBox cbxSample;
// We also create a constructor that accepts the entire item row
// and does the view lookups to find each subview
public ViewHolder(View itemView) {
// Stores the itemView in a public final member variable that can be used
// to access the context from any ViewHolder instance.
super(itemView);
rlyItem = (RelativeLayout) itemView.findViewById(R.id.item__rly);
cbxSample = (CheckBox) itemView.findViewById(R.id.item_cbx);
}
}
// Usually involves inflating a layout from XML and returning the holder
#Override public ViewHolder onCreateViewHolder(ViewGroup parent,
int viewType) {
Context context = parent.getContext();
LayoutInflater inflater = LayoutInflater.from(context);
// Inflate the custom layout
View viewHolder = inflater.inflate(R.layout.item_layout, parent, false);
// Return a new holder instance
return new ViewHolder(viewHolder);
}
// Involves populating data into the item through holder
#Override public void onBindViewHolder(final ViewHolder viewHolder, int position) {
// Get the data model based on position
final YourData data = mDatas.get(position);
final RelativeLayout rlyItem = viewHolder.rlyItem;
CheckBox cbxSample = viewHolder.cbxSample;
rlyItem.setOnClickListener(new View.OnClickListener() {
#Override public void onClick(View view) {
mListener.onItemClicked(viewHolder.getLayoutPosition());
}
});
cbxSample.setOnClickListener(new View.OnClickListener() {
#Override public void onClick(View view) {
if (((CheckBox) v).isChecked()) {
cbxSample.setChecked(false);
} else {
cbxSample.setChecked(true);
}
// Inform to Activity or the Fragment where the RecyclerView reside.
mListener.onItemCheckBoxChecked(((CheckBox) v).isChecked(), viewHolder.getLayoutPosition());
}
});
}
#Override public int getItemCount() {
return mDatas.size();
}
Then, in your Activity or Fragment where RecyclerView code reside, you need to set the listener:
yourAdapter.setOnRecyclerViewItemClickListener(new YourAdapter.OnRecyclerViewItemClickListener() {
#Override
public void onItemClicked(int position) {
// Do something when item clicked.
}
#Override
public void onItemCheckBoxChecked(boolean isChecked, int position) {
// Do something when check box check state change.
}
});
Addition:
To hold the the state of item in your ReyclerView, you need to use SparseBooleanArray