可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
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.
回答1:
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; } };
回答2:
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