Problems with OnClick to remove item from within Adapter - android

I am new to using recyclerview and adapters. I have the RecyclerView and an Onclick working (thanks to Google: https://github.com/googlesamples/android-RecyclerView). It does have an setOnClickListener which writes to the Log. But I'm trying to figure out how to remove an item from the list when it is clicked - I can't figure out how to get to the ArrayList which the adapter is using and run notifyItemInserted to update the display.
In reviewing another post (Android RecyclerView addition & removal of items - Android RecyclerView addition & removal of items) it looks like paradite/Jared Burrows were able to get it running. But some of the code appears to be missing and I was hoping that someone could fill in the holes for me. (I couldn't comment on this other post to ask the question there).
For example, I don't see that mItemClickListener is defined anywhere. I'm also not sure of the connection between the class which extends the RecyclerView.Adapter and the class which extends the RecyclerView.ViewHolder.
Here is my RecyclerView.Adapter:
public class RVAdapter1 extends RecyclerView.Adapter<RVAdapter1.ViewHolder> {
private static final String TAG = "debug";
private int itemCounter = 0;
private List<String> feedItemList;
public static class ViewHolder extends RecyclerView.ViewHolder {
private final TextView textView;
public ViewHolder(View v) {
super(v);
v.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Log.d(TAG, "Element " + getPosition() + " clicked.");
//feedItemList.remove(getPosition());
//notifyItemRemoved(getPosition());
}
});
textView = (TextView) v.findViewById(R.id.textView);
}
public TextView getTextView() {
return textView;
}
}
public RVAdapter1(List<String> dataSet) {
feedItemList = dataSet;
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
View v = LayoutInflater.from(viewGroup.getContext())
.inflate(R.layout.text_row_item, viewGroup, false);
return new ViewHolder(v);
}
#Override
public void onBindViewHolder(ViewHolder viewHolder, final int position) {
Log.d(TAG, "Element " + position + " set.");
viewHolder.getTextView().setText(String.valueOf(feedItemList.get(position)));
}
#Override
public int getItemCount() {
return feedItemList.size();
}
public void addItem(int position, String data) {
feedItemList.add(position, data);
notifyItemInserted(position);
Log.d(TAG,"adapter list length=" + feedItemList.size());
}
}
I am trying to use the adapter from the other StackOverflow question, but I am unsure of how to connect (or combine?) the two adapters and where the mItemClickListener comes from).
public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener{
public CardView mCardView;
public TextView mTextViewTitle;
public TextView mTextViewContent;
public ImageView mImageViewContentPic;
//......
public ImageView imgViewRemoveIcon;
public ViewHolder(View v) {
super(v);
mCardView = (CardView) v.findViewById(R.id.card_view);
mTextViewTitle = (TextView) v.findViewById(R.id.item_title);
mTextViewContent = (TextView) v.findViewById(R.id.item_content);
mImageViewContentPic = (ImageView) v.findViewById(R.id.item_content_pic);
//......
imgViewRemoveIcon = (ImageView) v.findViewById(R.id.remove_icon);
mTextViewContent.setOnClickListener(this);
imgViewRemoveIcon.setOnClickListener(this);
v.setOnClickListener(this);
mTextViewContent.setOnLongClickListener(new View.OnLongClickListener() {
#Override
public boolean onLongClick(View view) {
if (mItemClickListener != null) {
mItemClickListener.onItemClick(view, getPosition());
}
return false;
}
});
}
#Override
public void onClick(View v) {
//Log.d("View: ", v.toString());
//Toast.makeText(v.getContext(), mTextViewTitle.getText() + " position = " + getPosition(), Toast.LENGTH_SHORT).show();
if(v.equals(imgViewRemoveIcon)){
removeAt(getPosition());
}else if (mItemClickListener != null) {
mItemClickListener.onItemClick(v, getPosition());
}
}
}
public void setOnItemClickListener(final OnItemClickListener mItemClickListener) {
this.mItemClickListener = mItemClickListener;
}
public void removeAt(int position) {
mDataset.remove(position);
notifyItemRemoved(position);
notifyItemRangeChanged(getPosition, mDataSet.size());
}
This may be a trivial question but I certainly would appreciate any help that anyone is willing to offer... Thanks!

From what I can understand you're having trouble knowing which item has been clicked? So you need the getPosition() method.
My advice would be to use the setTag() method of views, where the tag will be the position of the feed item in your list. It should look something like this:
#Override
public void onBindViewHolder(ViewHolder viewHolder, final int position) {
Log.d(TAG, "Element " + position + " set.");
viewHolder.getTextView()
.setText(String.valueOf(feedItemList.get(position)));
viewHolder.getRemoveIcon().setTag(position);
}
After this create an onClickListener like this:
#Override
public void onClick(View v) {
int position = (Integer)v.getTag();
feedItemList.remove(position);
notifyItemRemoved(position);
}
For this to work you can make the adapter extend the View.OnClickListener, that way you have access to the array and to the notify methods.

Ok, I got it to work. Instead of having the ViewHolder be a "public static class" I needed to make it just "public class". Then I was able to modify my arraylist directly from the setOnClickListener block:
public class ViewHolder extends RecyclerView.ViewHolder {
private final TextView textView;
public ViewHolder(View v) {
super(v);
v.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Log.d(TAG, "Element " + getPosition() + " clicked.");
feedItemList.remove(getPosition());
notifyItemRemoved(getPosition());
}
});
textView = (TextView) v.findViewById(R.id.textView);
}
public TextView getTextView() {
return textView;
}
}

Related

hide/show a view(image or button) on a single item click in a recyclerview list

I really need some help regarding the recyclerview list.
Suppose there is a list with 10 items, Suppose i click one item (at position 1), i need make the view(button/image) visible on that particular item clicked. But when i will click any other item (at position 5) then the view(button/image)should be visible on position 5 and not on position 1. Can anyone tell me how can i achieve this result ? I would really appreciate if anybody help me with this. If you want some more details please do comment.
Thanks.
in recyclerview adapter when handling click listener in onBindViewHolder(Holder, Position) method you must choose the position of the view not fixed number(eg: 1,2 ,3)
ex:
=========
#Override
public void onBindViewHolder(final YourHolder holder, final int position) {
holder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
view.setVisibility(View.VISIBLE);
}
});
i hope this code is good enough to explain the way to do that:
public class myAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private List<Object> list;
public myAdapter(List<Object> list){
this.list=list;
}
ItemViewHolder openedRow=null;
#Override
public RecyclerView.ViewHolder onCreateViewHolder(final ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_list, parent, false);
ItemViewHolder view = new ItemViewHolder(v);
v.setOnClickListener(this);
return view;
}
#Override
public void onBindViewHolder(final RecyclerView.ViewHolder holder, final int position) {
final ItemViewHolder myRowHolder = (ItemViewHolder) holder;
myRowHolder.itemView.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View v) {
if(openedRow!=null)
{
openedRow.image.setVisibility(View.GONE);
}
openedRow=myRowHolder;
openedRow.image.setVisibility(View. VISIBLE);
}
});
}
public static class ItemViewHolder extends RecyclerView.ViewHolder {
ImageView image;
public ItemViewHolder(View itemView) {
super(itemView);
image = (ImageView)
itemView.findViewById(R.id.img_item_main);
}
}
}
I've updated mi code, this is working fine!
You need to add a boolean attribute to your ItemAdapter (the item you inflate on the recyclerView).
public class YourItem{
private String title;
private String image;
private boolean showView;
public String getTitle() {
return title;
}
public String getImage() {
return image;
}
public void setShowView(boolean showView) {
this.showView = showView;
}
public boolean mustShowView() {
return showView;
}
}
Then on your Adapter:
public class YourAdapter extends RecyclerView.Adapter<YourAdapter.MyViewHolder> {
...
private int lastPosition;
...
class MyViewHolder extends RecyclerView.ViewHolder {
private TextView title;
private ImageView image;
private View.OnClickListener onRowClicked = new View.OnClickListener() {
#Override
public void onClick(View view) {
if (lastPosition != getAdapterPosition()) {
Prize lastItem = getItem(lastPosition);
lastItem.setShowView(false);
adapterList.set(lastPosition, lastItem);
lastPosition = getAdapterPosition();
}
Prize item = getItem(getAdapterPosition());
item.setShowView(!item.mustShowView());
adapterList.set(getAdapterPosition(), item);
notifyDataSetChanged();
}
};
MyViewHolder(View itemView) {
super(itemView);
image = (ImageView) itemView.findViewById(R.id.image);
title = (TextView) itemView.findViewById(R.id.prize_title);
itemView.setOnClickListener(onRowClicked);
}
void bind(final Prize item) {
title.setText(item.getTitle().toUpperCase());
Picasso.with(context).load(item.getImage()).into(image);
image.setVisibility(item.mustShowView() ? View.VISIBLE : View.GONE);
}
}
}
I had this problem and change these:
1-Don't set attribute of android:visibility="visible" or "gone" in xml
2-Set this attribute in function of onBindViewHolder() in adapter():
holder.yourView.setVisibility(View.GONE);
holder.yourBottun.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (!(holder.yourView.isShown() ) {
holder.yourView.setVisibility(View.VISIBLE);
}
}
});

Button functionality in Fragment representing a list

In my app I have a Fragment representing a list of items.
This is done using a RecyclerViewAdapter. I have implemented an OnListFragmentInteractionListener and therefore if I click an item in the list my app does something.
That works correctly. However, I decided I want to also add a button inside that item. So if I click anywhere other than the button but inside that item's borders, it will proceed with functionality as before, but if I click on the button, it will do something else.
My question is, where do I implement this functionality?
The XML file representing an item in the list is just a couple of text views and a FloatingActionButton.
I thought I have to implement this in my adapter, but where exactly? My adapter looks like this:
public class ContractRecyclerViewAdapter extends RecyclerView.Adapter<ContractRecyclerViewAdapter.ViewHolder> {
private final List<Contract> mValues;
private final OnListFragmentInteractionListener mListener;
public ContractRecyclerViewAdapter(List<Contract> items, OnListFragmentInteractionListener listener) {
mValues = items;
mListener = listener;
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.fragment_contract_item, parent, false);
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(final ViewHolder holder, int position) {
holder.mItem = mValues.get(position);
holder.mSell.setText(mValues.get(position).getSell());
if (holder.mDescription != null) {
holder.mDescription.setText(mValues.get(position).getDescription());
}
// TODO: Get the price from parameters?
holder.mPrice.setText(((Double) new Random().nextDouble()).toString());
holder.mView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (null != mListener) {
// Notify the active callbacks interface (the activity, if the
// fragment is attached to one) that an item has been selected.
mListener.onListFragmentInteraction(holder.mItem);
}
}
});
holder.mBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
}
});
}
#Override
public int getItemCount() {
return mValues.size();
}
public void addContract(Contract contract) {
mValues.add(contract);
}
public class ViewHolder extends RecyclerView.ViewHolder {
public final View mView;
public final TextView mSell;
public final TextView mDescription;
public final TextView mPrice;
public final FloatingActionButton mBtn;
public Contract mItem;
public ViewHolder(View view) {
super(view);
mView = view;
mSell = (TextView) view.findViewById(R.id.company_text);
mDescription = (TextView) view.findViewById(R.id.contract_description);
mPrice = (TextView) view.findViewById(R.id.price_text);
mBtn = (FloatingActionButton) view.findViewById(R.id.buy_button_from_list);
}
#Override
public String toString() {
return super.toString() + " '" + mSell.getText() + ", " +
mDescription.getText() + "'";
}
}
}
The problem is that wherever I implement the onClickListener for my FloatingActionButton I'll need to have access to my SharedPreferences, so I think I will have to implement it in an Activity class (or Fragment class). Is that true? If I go this way then I'll have to implement it in the Fragment whose content is this view, but then how will I know the position of the item selected?
Thanks.
You can create another method inside your interface,
private interface OnListFragmentInteractionListener {
void onListFragmentInteraction(Contract mItem);
void onButtonClicked(Contract mItem); // You may want to edit the arguments of the method
}
Implement the onButtonClicked in your activity and do your stuff there.
Call the method inside your onClick of the Button as follows,
holder.mBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (null != mListener) {
mListener.onButtonClicked(holder.mItem);
}
}
});
how will I know the position of the item selected?
To get the position of item selected you can utilize the getAdapterPosition() method of RecyclerView.ViewHolder's class inside your View.OnClickListener.
holder.btnXyz.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
int position = holder.getAdapterPosition();
Model item = items.get(position);
/** your code **/
}
});

Firebase UI RecyclerView onClick

I am using Firebase UI FirebaseRecyclerAdapter to populate a RecyclerView. I managed to get click events from components of my item view (the title), but not for anywhere in the item view, which is what I need. I followed google sample.
In my Activity:
private void setRecyclerView() {
recyclerView = (RecyclerView) findViewById(R.id.recycler_view_gigs);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
mAdapter = new FirebaseRecyclerAdapter<Gig, GigViewHolder>(Gig.class,
R.layout.list_item_card,
GigViewHolder.class,
reference) {
#Override
protected void populateViewHolder(final GigViewHolder viewGig, Gig model, final int position) {
viewGig.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Log.i(Utils.TAG, "onItemClickGeneral: position " + position);
// this doesn't work
}
});
viewGig.bindToGig(model, new View.OnClickListener() {
#Override
public void onClick(View v) {
Log.i(Utils.TAG, "onItemClickTitle: position " + position);
// this works
}
});
}
};
recyclerView.setAdapter(mAdapter);
}
and my ViewHolderClass:
public class GigViewHolder extends RecyclerView.ViewHolder {
ImageView ivIconArtist;
TextView tvArtist;
TextView tvVenue;
TextView tvDate;
public GigViewHolder(View view) {
super(view);
ivIconArtist = (ImageView) view.findViewById(R.id.iv_list_item_icon_artist);
tvArtist = (TextView) view.findViewById(R.id.tv_list_item_artist);
tvVenue = (TextView) view.findViewById(R.id.tv_list_item_venue);
tvDate = (TextView) view.findViewById(R.id.tv_list_item_date);
}
public void bindToGig(Gig gig, View.OnClickListener clickListener) {
tvArtist.setText(gig.getArtist());
tvVenue.setText(gig.getVenue());
tvDate.setText(gig.getDate());
tvArtist.setOnClickListener(clickListener);
}
}
I tried the custom onclicklistener + interface suggested in other answers, no luck either.
Implementing click and long click listener for entire row / items in FirebaseRecyclerViewAdapter.
I did this in this way.
First, define an interface in your ViewHolder class to send callbacks.
Inside its constructor, you can set click/long-click listener for entire row or a single componnent.
Then override onCreateViewHolder of FirebaseRecyclerAdapter where you will implement this interface.
IMPLEMENTATION
My FirebaseViewHolder class.
public class FirebaseViewHolder extends RecyclerView.ViewHolder {
public ImageView mImageView;
public TextView mPostTitle;
public TextView mPostDesc;
public FirebaseViewHolder(View itemView) {
super(itemView);
mImageView = (ImageView) itemView.findViewById(R.id.image_recyclerview);
mPostTitle = (TextView) itemView.findViewById(R.id.tv_title_recyclerview_item);
mPostDesc = (TextView) itemView.findViewById(R.id.tv_desc_recyclerview_item);
//listener set on ENTIRE ROW, you may set on individual components within a row.
itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
mClickListener.onItemClick(v, getAdapterPosition());
}
});
itemView.setOnLongClickListener(new View.OnLongClickListener() {
#Override
public boolean onLongClick(View v) {
mClickListener.onItemLongClick(v, getAdapterPosition());
return true;
}
});
}
private FirebaseViewHolder.ClickListener mClickListener;
//Interface to send callbacks...
public interface ClickListener{
public void onItemClick(View view, int position);
public void onItemLongClick(View view, int position);
}
public void setOnClickListener(FirebaseViewHolder.ClickListener clickListener){
mClickListener = clickListener;
}
}
Creating the FirebaseRecyclerAdapter.
FirebaseRecyclerAdapter<Post, FirebaseViewHolder> adapter = new FirebaseRecyclerAdapter<Post, FirebaseViewHolder>(
Post.class,
R.layout.recyclerview_list_item,
FirebaseViewHolder.class,
databaseReference
) {
#Override
protected void populateViewHolder(FirebaseViewHolder viewHolder, Post model, int position) {
Picasso.with(getActivity())
.load(model.image_url)
.into(viewHolder.mImageView);
Log.v(TAG, model.image_url);
//viewHolder.mImageView.setImageResource(R.mipmap.ic_launcher);
viewHolder.mPostTitle.setText(model.title);
viewHolder.mPostDesc.setText(model.desc);
}
#Override
public FirebaseViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
FirebaseViewHolder viewHolder = super.onCreateViewHolder(parent, viewType);
viewHolder.setOnClickListener(new FirebaseViewHolder.ClickListener() {
#Override
public void onItemClick(View view, int position) {
Toast.makeText(getActivity(), "Item clicked at " + position, Toast.LENGTH_SHORT).show();
}
#Override
public void onItemLongClick(View view, int position) {
Toast.makeText(getActivity(), "Item long clicked at " + position, Toast.LENGTH_SHORT).show();
}
});
return viewHolder;
}
};
There are several answers to this question. One that worked for me was the answer provided by Frank van Puffelen how-to-implement-a-setonitemclicklistener-firebaserecyclerviewadapter
You need to change few things.
Before GigViewHolder constructor inside your public class GigViewHolder extends RecyclerView.ViewHolder define a global variable like this View itemView;
Inside GigViewHolder constructor, assign this variable the view passed as a parameter on your constructor like this this.itemView= view;
Then use this itemView in your populateViewHolder method as you had done as also shown
viewGig.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Log.i(Utils.TAG, "onItemClickGeneral: position " + position);
// This WORKS, write your TODO here
}
});
You can also explore other options on the following links:
RecyclerView onClick

Multi selection in RecyclerView

I have list of data with CheckBox. I need to check or uncheck my Check Box from my RecyclerView. When I am trying this more than one check box is selected.
public class AttendanceAdapter extends RecyclerView.Adapter<AttendanceAdapter.MyStudentsViewHolder>{
private LayoutInflater inflater;
private Context contexts;
List<studinformation> data= Collections.emptyList();
public AttendanceAdapter(Context context,List<studinformation> data){
inflater=LayoutInflater.from(context);
this.data=data;
this.contexts=context;
}
#Override
public MyStudentsViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view= inflater.inflate(R.layout.customrow_students,parent,false);
MyStudentsViewHolder holder=new MyStudentsViewHolder(view);
return holder;
}
#Override
public void onBindViewHolder(MyStudentsViewHolder holder, int position) {
studinformation current=data.get(position);
holder.studentid.setText(current.studID);
holder.studentname.setText(current.studName);
holder.studentid.setSelected(true);
}
#Override
public int getItemCount() {
return data.size();
}
class MyStudentsViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
CheckBox studentid;
TextView studentname;
public MyStudentsViewHolder(View itemView) {
super(itemView);
studentid= (CheckBox) itemView.findViewById(R.id.ChkSid);
studentname= (TextView) itemView.findViewById(R.id.textName);
studentid.setOnClickListener(this);
}
#Override
public void onClick(View v) {
Toast.makeText(contexts, "Item Clicked At" + getPosition(), Toast.LENGTH_SHORT).show();
if(getPosition()==0) {
// Intent intent = new Intent(contexts, SubActivity.class);
// contexts.startActivity(intent);
}
}
}
}
RecyclerView will reuse the view.so when you return after scrolling it will reset the data it's happening because you are not setting your checkbox selected or not.
In your StudInformation model class create a property isSelected
public class StudInformation
{
private boolean isSelected=false;
public void setSelected(boolean param)
{
this.isSelected=param;
}
public boolean isSelected()
{
return this.isSelected;
}
}
Inside onClick
#Override
public void onClick(View v) {
data.get(getLayoutPosition()).setSelected(studentid.isChecked());
}
In onBindViewHolder
#Override
public void onBindViewHolder(MyStudentsViewHolder holder, int position) {
.....
studinformation current=data.get(position);
holder.studentid.setSelected(current.isSelected());
}
Cross reference link
you have to use setTag() method to get position of each checkbox.
Use this code instead of holder.studentid.setSelected(true); and remove studentid.setOnClickListener(this);
holder.studentid.setChecked(data.get(position).isSelected());
holder.studentid.setTag(data.get(position));
holder.studentid.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
CheckBox cb = (CheckBox) v;
String id = String.valueOf(cb.getTag());
Toast.makeText(
v.getContext(),
"Clicked on Checkbox: " + id, Toast.LENGTH_LONG).show();
}
});

How to add OnClickListner to CardView?

I am working with RecyclerView and CardView. I want to attach OnClickListner to each card. I tried with many answers available on stackoverflow, but they are not working for me. So far I have tried -
public class SubjectAdapter extends RecyclerView.Adapter<SubjectAdapter.ViewHolder> implements View.OnClickListener,
View.OnLongClickListener{
private static final String LOGCAT = "SubjectAdapter";
private final Context mContext;
List<Subject> SubjectsList;
public SubjectAdapter(Context context) {
super();
this.mContext = context;
SQLiteDatabase.loadLibs(mContext);
DBHelper myDbHelper = new DBHelper(mContext);
SubjectsList = new ArrayList<Subject>();
SubjectsList = myDbHelper.getAllSubjects();
myDbHelper.close();
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
View v = LayoutInflater.from(viewGroup.getContext())
.inflate(R.layout.subject_cardview_row, viewGroup, false);
ViewHolder viewHolder = new ViewHolder(v);
// Below two lines are NOT working
viewHolder.tvSubjectName.setOnClickListener(this);
//viewHolder.setOnClickListener(this);
return viewHolder;
}
#Override
public void onBindViewHolder(ViewHolder viewHolder, int i) {
Subject subject = SubjectsList.get(i);
viewHolder.tvSubjectName.setText(subject.getSubject_Name());
viewHolder.tvCounts.setText(String.valueOf(subject.getSubject_Number_of_Questions()));
// Below two lines are NOT working
viewHolder.tvSubjectName.setOnClickListener(this);
//viewHolder.setOnClickListener(this);
}
#Override
public int getItemCount() {
return SubjectsList.size();
}
#Override
public void onClick(View v) {
// It's not working either
ViewHolder holder = (ViewHolder) v.getTag();
int position = holder.getPosition();
if (v.getId() == holder.tvSubjectName.getId()){
Log.d(LOGCAT, "tvSubjectName onClick at" + position);
//Toast.makeText(mContext, "tvSubjectName onClick at" + position, Toast.LENGTH_LONG).show();
} else {
Log.d(LOGCAT, "RecyclerView Item onClick at " + position);
//Toast.makeText(mContext, "RecyclerView Item onClick at " + position, Toast.LENGTH_LONG).show();
}
}
#Override
public boolean onLongClick(View v) {
return false;
}
class ViewHolder extends RecyclerView.ViewHolder {
public TextView tvSubjectName;
public TextView tvCounts;
public ViewHolder(View itemView) {
super(itemView);
tvSubjectName = (TextView) itemView.findViewById(R.id.tv_subject_name);
tvCounts = (TextView) itemView.findViewById(R.id.tv_text_counts);
}
}
}
As one can see, I have tried setOnClickListener with both onCreateViewHolder and onBindViewHolder, also as separate onClick, but none of them seems to be working for me. So, I want to know, How to add OnClickListner to CardView?
View returned by onClick does not necessarily correspond to View row hierarchy of the recycler view.
I think you should modify onBindViewHolder with
#Override
public void onBindViewHolder(final ViewHolder viewHolder, final int i) {
final Subject subject = SubjectsList.get(i);
viewHolder.tvSubjectName.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View v) {
Log.d(LOGCAT, "tvSubjectName onClick at" + i);
// etc
}
});
...
}
If you use long click then replace View.OnClickListener with View.OnLongClickListener and onClick with onLongClick.
This worked for me !
Put the setOnClickListener-method inside the constructor of your ViewHolder class.
class ViewHolder extends RecyclerView.ViewHolder
{
public TextView tvSubjectName;
public TextView tvCounts;
public ViewHolder(View itemView)
{
super(itemView);
tvSubjectName = (TextView) itemView.findViewById(R.id.tv_subject_name);
tvCounts = (TextView) itemView.findViewById(R.id.tv_text_counts);
itemView.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View v)
{
//write here the code for wathever you want to do with a card
//...
}
});
}
}
Check out Lucas Rocha's new TwoWayView API.
TwoWayLayoutManager is a simple API on top of LayoutManager that does all the laborious work for you so that you can focus on how the child views are measured, placed, and detached from the RecyclerView.
Follow his site and implementation of the API is relatively simple and might help you through some of the difficult complexities RecyclerView and CardView pose.
http://lucasr.org/2014/07/31/the-new-twowayview/
Set OnClickListener to itemView in RecyclerView.ViewHolder constructor, also you can fetch position of cardView using getAdapterPosition() method which can help you to pass the data to new activity using putExtra method of intent. doc for getAdapterPosition method
`
class ViewHolder extends RecyclerView.ViewHolder
{
public TextView tvSubjectName;
public TextView tvCounts;
public ViewHolder(View itemView)
{
super(itemView);
tvSubjectName = (TextView) itemView.findViewById(R.id.tv_subject_name);
tvCounts = (TextView) itemView.findViewById(R.id.tv_text_counts);
itemView.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View v)
{
int position = getAdapterPosition();
// use position to put extra data
}
});
}
`
If you really want to implement onclick listener then do the following
add a View object in your ViewHolderClass and initialize it to the itemView recieved in the constructor
2.setOnClickListener to the view object you declared(in ViewHolder) onBindViewHolder in the Adapter class
this will work for the entire cardView

Categories

Resources