Why Single Click don't works on RecyclerView items - android

I have a simple RecyclerView with an Interface that is linked to the activity. The Issue is the items in the recyclerView need double click in order to perform an action.
This is the AllProductsAdapter Code :
public class AllProductsAdapter extends RecyclerView.Adapter<AllProductsAdapter.ViewHolder> {
RecyclerViewClickInterfaceNew recyclerViewClickInterface;
List<ProductsModel> productsModelList;
Context context;
public AllProductsAdapter(List<ProductsModel> productsModelList, Context context, RecyclerViewClickInterfaceNew recyclerViewClickInterface) {
this.productsModelList = productsModelList;
this.context = context;
this.recyclerViewClickInterface = recyclerViewClickInterface;
}
#NonNull
#Override
public AllProductsAdapter.ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(context).inflate(R.layout.product_items, parent, false);
return new AllProductsAdapter.ViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull AllProductsAdapter.ViewHolder holder, int position) {
ProductsModel productsModel = productsModelList.get(position);
PicassoTrustAll.getInstance(context)
.load(productsModel.getProduct_image())
.into(holder.catImage);
}
#Override
public int getItemCount() {
return productsModelList.size();
}
class ViewHolder extends RecyclerView.ViewHolder {
ImageView catImage;
TextView catName;
CardView categoryCard;
public ViewHolder(#NonNull View itemView) {
super(itemView);
catImage = itemView.findViewById(R.id.catImage);
catName = itemView.findViewById(R.id.catName);
categoryCard = itemView.findViewById(R.id.categoryCard);
itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (recyclerViewClickInterface != null)
recyclerViewClickInterface.onItemClick(v, getAdapterPosition());
}
});
}
}
This is my RecyclerViewClickInterfaceNew :
public interface RecyclerViewClickInterfaceNew {
void onItemClick(View view , int position);
void onLongItemClick(int position);
}
This is my MainActivity code :
#Override
public void onItemClick(View view , int position) {
ImageView img= view.findViewById(R.id.catImage);
img.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(AllProductsList.this, "Imgclciked", Toast.LENGTH_SHORT).show();
}
});
}
Here in the MainActivity, the Toast shows after clicking 2 times on the Image. How can i fix it to a normal single click ? Please let me know your answer.

From this code
#Override
public void onItemClick(View view , int position) {
//when different item is FIRST clicked, a new instance of catImage is produced
ImageView img= view.findViewById(R.id.catImage);
//the img onClick is set here to require a second click
img.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(AllProductsList.this, "Imgclciked", Toast.LENGTH_SHORT).show();
}
});
}
For each new item on the Recycler View, you reset the click handling.
I'll suggest you set the onClickListener ON the ViewHolder. It's not the best practice but it'll suffice for your code

I think that's because of you are using NestedScrollView ,
you should add this line to your recyclerview
android:nestedScrollingEnabled="false"

Related

itemView.getTag() returns -1

I am using RecyclerView and I want to view the the data of list item that I click on. I'm using itemView.getTag() to get the value of index and typecasting it to my CustomAdapter.
I tried various ways but not to help. please help me.
Here's my code:
public class DonorAdapter extends RecyclerView.Adapter<DonorAdapter.ViewHolder> {
ArrayList<Donor> donorsList;
ItemSelected activity;
public interface ItemSelected{
void onItemClicked(int index);
}
public DonorAdapter(Context context, ArrayList<Donor> list){
activity = (ItemSelected) context;
donorsList = list;
}
public class ViewHolder extends RecyclerView.ViewHolder
{
ImageView ivDonorGender;
TextView tvListName;
TextView tvBloodGroup;
public ViewHolder(#NonNull final View itemView) {
super(itemView);
ivDonorGender = itemView.findViewById(R.id.ivDonorGender);
tvListName = itemView.findViewById(R.id.tvListName);
tvBloodGroup = itemView.findViewById(R.id.tvListBloodGroup);
itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
activity.onItemClicked(donorsList.indexOf((Donor) itemView.getTag()));
}
});
}
}
#NonNull
#Override
public DonorAdapter.ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.donors_list, parent, false);
return new ViewHolder(v);
}
#Override
public void onBindViewHolder(#NonNull DonorAdapter.ViewHolder holder, int position) {
holder.tvListName.setText(donorsList.get(position).getName());
holder.tvBloodGroup.setText(donorsList.get(position).getSurname());
}
}
#Override
public int getItemCount() {
return donorsList.size();
}
}
I am new to android so pardon me if I can't explain properly
Here's the problematic part
itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
activity.onItemClicked(donorsList.indexOf((Donor)
itemView.getTag()));
}
I think you need to set the tag for each recycled item in onBindViewHolder
#Override
public void onBindViewHolder(#NonNull DonorAdapter.ViewHolder holder, int position) {
holder.tvListName.setText(donorsList.get(position).getName());
holder.tvBloodGroup.setText(donorsList.get(position).getSurname());
holder.itemView.setTag(donorsList.get(position)); // change here
}
}

Attach click listener to each component of recycler view items [duplicate]

This question already has answers here:
Why doesn't RecyclerView have onItemClickListener()?
(31 answers)
RecyclerView onClick
(49 answers)
Closed 3 years ago.
I am learning Android Development. Struggling with this issue since 24 hours, need help.
On my each recycle view item I've two views ePaper & Website. I want to attach different on click listeners on the entire item, ePaper view and website view
In the above image, I need to put 3 click listeners
1. Click on red block 1 - do X (Intent to another activity)
2. Click on red block 2 - do Y (Intent to another activity)
3. Click on green block, entire item view - do Z (Dialog)
Tried many solutions. But, when I click red block, the listener in green block also comes to action in addition to listener in red block.
In the MainActivity
recyclerView.addOnItemTouchListener(new RecyclerTouchListener(getApplicationContext(),
recyclerView, new ClickListener() {
String userid = Utils.getUserId(getApplicationContext());
#Override
public void onClick(View view, final int position) {
// Set listeners here for complete card view
final NewsPapersDataModel currentPaper = newsPapersList.get(position);
Log.d("TAG","Clicked 1");
newsSelectionDialog(currentPaper.getEpaper(),currentPaper.getWebsite());
}
#Override
public void onLongClick(View view, int position) {
Toast.makeText(MainActivity.this, "Long press on position :" + position, Toast.LENGTH_LONG).show();
}
}));
In the NewsPaperAdapter
public void onBindViewHolder(#NonNull final CustomViewHolder holder, int position) {
// Log.d("TAG","Holder is "+newsList);
final NewsPapersDataModel currentItem = newsList.get(position);
final String ePaperUrl = currentItem.getEpaper();
final String webSiteUrl = currentItem.getWebsite();
final String paperName = currentItem.getName();
holder.paperNameView.setText(newsList.get(position).getName());
if (TextUtils.isEmpty(currentItem.getEpaper())) {
// Log.d("TAGG","ePaper - "+currentItem.getEpaper()+" Website - "+currentItem.getWebsite());
holder.ePaperView.setVisibility(View.GONE);
} else if (TextUtils.isEmpty(currentItem.getWebsite())) {
holder.websiteView.setVisibility(View.GONE);
}
holder.ePaperView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
saveLinksToDb(userid, "ePaper", ePaperUrl);
Intent intent = new Intent(context, NewsAdvancedWebViewActivity.class);
intent.putExtra("url", ePaperUrl);
context.startActivity(intent);
}
});
holder.websiteView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
saveLinksToDb(userid, "Website", webSiteUrl);
Intent intent = new Intent(context, NewsAdvancedWebViewActivity.class);
intent.putExtra("url", webSiteUrl);
intent.putExtra("paperName",paperName);
context.startActivity(intent);
}
});
}
Please help me.
You need to create an interface in your adapter for click listeners and add onclick methods for every item you want.
Please look into the code below.
In your adapter, create interface
public interface OnClickListener {
void onPaperViewClick(View view, int position);
void onWebsiteViewClick(View view, int position);
}
And create method to set click listener from activity
public void setOnClickListener(OnClickListener listener) {
this.onClickListener= listener;
}
And in your onBindViewHolder method,
holder.ePaperView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
onClickListener.onPaperViewClick(view, position);
});
holder.websiteView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
onClickListener.onWebsiteViewClick(view, position);
});
and lastly, in your activity, set
recyclerViewAdapter.setOnClickListener(new NewsPaperAdapter.OnClickListener(){
#override
void onPaperViewClick(View view, int position){
// code to handle paper click
}
#override
void onPaperViewClick(View view, int position){
// code to handle website click
}
};
Remove your TouchListener from MainActivity and add ClickListener/ LonCkickListener inside your adapter.
onBindViewHolder(){
//rest of your code
holder.itemView.setOnClickListener(new OnClickListener{
#Override
public void onClick(View view) {
// Click implementation here
}
#Override
public void onLongClick(View view) {
// Long click implementation here
}
})
}
And inside your CustomViewHolder:
public class CustomViewHolder extends RecyclerView.ViewHolder{
// Other fields
View itemView;
public CustomViewHolder(View view){
// rest of initialization
itemView = view;
}
}
EDIT (OP wants to handle application logic inside Activity)
Create an interface class named RecyclerViewActionListener:
public interface RecyclerViewActionListener {
void onViewClicked(int clickedViewId, int clickedItemPosition);
void onViewLongClicked(int clickedViewId, int clickedItemPosition);
}
Then modify your RecyclerViewAdpater to have an additional field in constructor. We will pass listener from Activity to this adpater when we create Adapter:
public class RecyclerViewAdpater extends RecyclerView.Adapter<RecyclerViewAdpater.CustomViewHolder>{
private RecyclerViewActionListener mListener;
public RecyclerViewAdpater(ArrayList<Object> yourData,RecyclerViewActionListener mListener) {
this.mListener = mListener;
}
#NonNull
#Override
public CustomViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item, parent, false );
final CustomViewHolder holder = new CustomViewHolder(view);
holder.webView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
mListener.onViewClicked(view.getId(), holder.getAdapterPosition());
}
});
holder.paperView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
mListener.onViewClicked(view.getId(), holder.getAdapterPosition());
}
});
holder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
mListener.onViewClicked(view.getId(), holder.getAdapterPosition());
}
});
holder.itemView.setOnLongClickListener(new View.OnLongClickListener() {
#Override
public boolean onLongClick(View view) {
mListener.onViewLongClicked(view.getId(), holder.getAdapterPosition());
return false;
}
});
return holder;
}
public class CustomViewHolder extends RecyclerView.ViewHolder{
// Other fields
View itemView;
View webView;
View paperView;
public CustomViewHolder(View view){
super(view);
// rest of initialization
itemView = view;
}
}
}
And then implement RecyclerViewActionListener in your Activity and override methods from RecyclerViewActionListener:
public class MainActivity extends AppCompatActivity implements RecyclerViewActionListener {
RecyclerViewAdpater adapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main3);
// Skipped for the sake of brevity
// Pass your listener to adapter here
adapter = new RecyclerViewAdpater(yourData, this );
}
#Override
public void onViewClicked(int clickedViewId, int clickedItemPosition) {
switch (clickedItemPosition){
case R.id.web_view:
// Application logic when webview clicked
break;
case R.id.paper_view:
// Application logic when paperview clicked
break;
case R.id.recyclerview_item:
// Application logic when whole item clicked
break;
}
}
#Override
public void onViewLongClicked(int clickedViewId, int clickedItemPosition) {
switch (clickedViewId){
case R.id.recyclerview_item:
// Application logic when whole item long-clicked
break;
}
}
}
And in your xml file don't forget to assign ID to you views. Because we're detecting clicked view with their IDs.
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/recyclerview_item"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="#+id/web_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"/>
<ImageView
android:id="#+id/paper_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</RelativeLayout>
try in your NewsPaperAdapter class onClickListner to parent layout of adapter like below
holder.parentLayout.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
final NewsPapersDataModel currentPaper = newsPapersList.get(position);
Log.d("TAG","Clicked 1");
newsSelectionDialog(currentPaper.getEpaper(),currentPaper.getWebsite());
}
});
here parentLayout is your adapter item layout root view like Relative/Linear Layout

Disabling a RecyclerView

I'm facing the next problem.
I have a RecyclerView with the Adapter, the items, etc.
What I need is: Select an item in the recycler, change the color of that item, and then I have to disable the rest of the other items. It's like a RadioButton list.
I select one and disable the others. If I select again the same item, enable all the list.
I already have the onClick Button listener. I need to know if I have to reload again de list, If I have to loop and disable item by item, etc.
Thanks
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewHolder> {
private List<Human> humans;
private HumanClick selectedHuman;
#Inject
public MyAdapter() {
}
public void init(List<Human> humanList, SelectedHumanClick humanClick){
this.humans = humanList;
this.humanClick = humanClick;
}
#NonNull
#Override
public MyViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_Human, parent, false);
return new MyViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull final MyViewHolder holder, int position) {
final Human human = Humans.get(position);
holder.bind(Humans.get(position));
holder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
selectedHumanClick.onSelectedHumanClick(Human);
}
});
}
#Override
public int getItemCount() {
return humans != null ? Humans.size() : 0;
}
public final class MyViewHolder extends RecyclerView.ViewHolder {
#BindView(R.id.text_view_human_name)
TextView textView;
#BindView(R.id.image_view_profile)
ImageView imageViewProf;
#BindView(R.id.image_view_radio_btn)
ImageView imageViewRB;
private boolean isChecked = false;
public MyViewHolder(View itemView) {
super(itemView);
ButterKnife.bind(this, itemView);
}
public void bind(final Human Human) {
itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
humanClick.onSelectedHumanClick(Human);
}
});
textView.setText(human.getName());
}
public void changeRBImage() {
if(!isChecked){
isChecked = true;
imageViewRB.setBackground(ContextCompat.getDrawable(imageViewRB.getContext(), R.drawable.selected));
}
else{
isChecked = false;
imageViewRB.setBackground(ContextCompat.getDrawable(imageViewRB.getContext(), R.drawable.not_selected));
}
}
}
My Recycler is defined inside a fragment here:
public class HumansFragment implenets HumanClick{
#BindView(R.id.recycler_humans)
RecyclerView humansRecyclerView;
#Inject
MyAdapter myAdapter;
.
.
.
public void loadHumans(List<Human> humans) {
myAdapter.init(Humans, this);
humansRecyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
humansRecyclerView.setAdapter(myAdapter);
}
#Override
public void humansClick(Human human) {
//TODO
}
}
I'm thinking in something like this, using setOnItemClickListener and check the position of the item clicked. The position is the index of the item clicked check the last event and new, if both are equal change color, if not dont do anything like disabling.
private ViewHolder(View itemView) {
super(itemView);
itemView.setOnClickListener(this);
textView = (TextView)view.findViewById(android.R.id.text1);
}
#Override
public void onClick(View view) {
Toast.makeText(view.getContext(), "position = " + getLayoutPosition(), Toast.LENGTH_SHORT).show();
//go through each item if you have few items within recycler view
if(getLayoutPosition()==0){
//Do whatever you want here
}else if(getLayoutPosition()==1){
//Do whatever you want here
}else if(getLayoutPosition()==2){
}else if(getLayoutPosition()==3){
}else if(getLayoutPosition()==4){
}else if(getLayoutPosition()==5){
}
//or you can use For loop if you have long list of items. Use its length or size of the list as
for(int i = 0; i<exampleList.size(); i++){
}
}
}
Or something smaller
RecyclerView recyclerView = findViewById(R.id.recycler);
recyclerView.addOnItemTouchListener(
new RecyclerItemClickListener(context, recyclerView ,new
RecyclerItemClickListener.OnItemClickListener() {
#Override public void onItemClick(View view, int position) {
// do whatever
}
#Override public void onLongItemClick(View view, int position) {
// do whatever
}
})
);

How to get image from recyclerview position clicked data and set it into another imageview?

I have an app which contains recyclerview with imageview and text.When I click on item based on position that is imageview i want image of that image view and set it to another Imageview.To do this I have made interface and implements its method in Activity but need to know that how do i do that
Adapter code:
public interface OnItemClicked {
void onItemClicked(int position);
}
public AvatarListAdapter(Context context, int[] arrayList) {
this.mContext = context;
this.dataModel = arrayList;
}
#Override
public AvatarListAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.avatar_items, parent, false);
return new AvatarListAdapter.ViewHolder(view);
}
#Override
public void onBindViewHolder(AvatarListAdapter.ViewHolder holder, final int position) {
holder.mAvatarImage.setImageResource(dataModel[position]);
holder.mAvatarImage.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
onClick.onItemClicked(position);
}
});
}
public void setOnClick(OnItemClicked onClick) {
this.onClick = onClick;
}
#Override
public int getItemCount() {
return dataModel.length;
}
public class ViewHolder extends RecyclerView.ViewHolder {
private CircleImageView mAvatarImage;
public ViewHolder(View itemView) {
super(itemView);
mAvatarImage = itemView.findViewById(R.id.img_avatar);
}
}
}
Activity code:
private void initializeActions() {
int numberOfColumns = 3;
mAvatarImages.setLayoutManager(new GridLayoutManager(AvatarProfileImage.this, numberOfColumns));
mAdapter = new AvatarListAdapter(AvatarProfileImage.this, avatar);
mAvatarImages.setAdapter(mAdapter);
mAdapter.setOnClick(this);
}
#Override
public void onItemClicked(int position) {
String pos = "You clicked at position " + position;
Toast.makeText(getApplicationContext(), "You clicked position" + pos, Toast.LENGTH_LONG).show();
mAvatarImages.setBackgroundResource(avatar[position]);
}
You can get data by position on OnClick().As you are using local drawable for image resource, One way to do is Modify your viewHolder as follows.This is just a one way you can also use ViewTag.
public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener{
private Circle mAvatarImage;
public ViewHolder(View itemView) {
super(itemView);
mAvatarImage = itemView.findViewById(R.id.img_avatar);
mAvatarImage.setOnClickListener(this);
}
#Override
public void onClick(View v) {
int postion =getAdapterPosition();
int image =arrayList[postion];
// Use this image to forward
}
}
Remove OnClick from onBindViewHolder.
Implement RecycleView onClick() method and get specified data while onclick position.have look
public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener{
private Circle mAvatarImage;
public ViewHolder(View itemView) {
super(itemView);
mAvatarImage = itemView.findViewById(R.id.img_avatar);
mAvatarImage.setOnClickListener(this);
}
#Override
public void onClick(View v) {
int position=arrayList[getAdapterPosition()];
String imagepath = arraylist.get(position).getImagePath
//you can use imagepath anywhere you want either be put in bundle or intent call
}
}
Adapter code should look like this
private final OnItemClickListener listenerOnItemClick;
public interface OnItemClickListener {
void onItemClick(int position); }
public AvatarListAdapter(Context context, int[] arrayList, OnItemClickListener listenerOnItemClick) {
this.mContext = context;
this.dataModel = arrayList;
this.listenerOnItemClick=listenerOnItemClick;
}
#Override
public AvatarListAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.avatar_items, parent, false);
return new AvatarListAdapter.ViewHolder(view); }
#Override
public void onBindViewHolder(AvatarListAdapter.ViewHolder holder, final int position) {
holder.mAvatarImage.setImageResource(dataModel[position]);
holder.mAvatarImage.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
onClick.onItemClicked(position);
}
}); }
public void setOnClick(OnItemClicked onClick) {
this.onClick = onClick; }
#Override
public int getItemCount() {
return dataModel.length; }
public class ViewHolder extends RecyclerView.ViewHolder {
private CircleImageView mAvatarImage;
public ViewHolder(View itemView) {
super(itemView);
mAvatarImage = itemView.findViewById(R.id.img_avatar);
} }
Activity Code
AvatarListAdapter.OnItemClickListener onItemClickListener = new AvatarListAdapter.OnItemClickListener() {
#Override
public void onItemClick(int position) {
//change your Image here
String pos = "You clicked at position " + position;
Toast.makeText(getApplicationContext(), "You clicked position" + pos, Toast.LENGTH_LONG).show();
mAvatarImages.setBackgroundResource(avatar[position]);
}
};
private void initializeActions() {
int numberOfColumns = 3;
mAvatarImages.setLayoutManager(new GridLayoutManager(AvatarProfileImage.this, numberOfColumns));
mAdapter = new AvatarListAdapter(AvatarProfileImage.this, avatar,onItemClickListener );
mAvatarImages.setAdapter(mAdapter);
mAdapter.setOnClick(this);
}

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

Categories

Resources