可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I want to set up an onClickListener within my RecyclerView adapter so I can easily refer to the other views to retrieve their tags.
Is it possible to set up an onClickListener in a RecyclerView adapter? How would I do it? Would it affect performance?
Here is my RecyclerView adapter:
public class PostRecyclerAdapter extends RecyclerView.Adapter<PostRecyclerAdapter.ViewHolder> { private Context context; private List<Post> mDataset; public static class ViewHolder extends RecyclerView.ViewHolder implements View.OnCreateContextMenuListener { public LinearLayout mainLayout; public TextView username; public ImageView image; public ViewHolder(LinearLayout view) { super(view); view.setOnCreateContextMenuListener(this); mainLayout = (LinearLayout) view.findViewById(R.id.main_view); username = (TextView) view.findViewById(R.id.username); image = (ImageView) view.findViewById(R.id.image); } } public PostRecyclerAdapter(Context context, List<Post> myDataset) { this.context = context; this.mDataset = myDataset; } @Override public PostRecyclerAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.post_layout, parent, false); ViewHolder vh = new ViewHolder((LinearLayout) view); return vh; } @Override public void onBindViewHolder(ViewHolder holder, int position) { Post postItem = mDataset.get(position); holder.username.setText(postItem.getUserame()); } @Override public int getItemCount() { return mDataset.size(); } }
回答1:
I would like to suggest a much simpler approach than the one given above. in your adapter you would have written static view holder class right for that add the following code
public static class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener{ // your views declared here CardView cardView; public ViewHolder(View itemView) { super(itemView); // your view initialised here cardView=itemView.findViewById(R.id.card_view); cardView.setOnClickListener(this); } @Override public void onClick(View v) { switch (v.getId()){ case R.id.card_view: // your logic break; } } }
by doing so you can handle individual click of your layout as well as the entire layout click
回答2:
You can use GestureDetector for this. This is very simple to use :
Create A class RecyclerTouchListener :
public class RecyclerTouchListener implements RecyclerView.OnItemTouchListener { private GestureDetector gestureDetector; private ClickListener clickListener; public RecyclerTouchListener(Context context, final RecyclerView recyclerView, final ClickListener 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.getChildPosition(child)); } return false; } @Override public void onTouchEvent(RecyclerView rv, MotionEvent e) { } @Override public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) { } public interface ClickListener { void onClick(View view, int position); void onLongClick(View view, int position); } }
and you can use this class as follow :
rvFilterOptions = (RecyclerView) rootView.findViewById(R.id.rvCommon); rvFilterOptions.setHasFixedSize(true); rvFilterOptions.addItemDecoration(new DividerItemDecoration(getActivity(), DividerItemDecoration.VERTICAL_LIST)); LinearLayoutManager mLayoutManager = new LinearLayoutManager(getActivity()); rvFilterOptions.setLayoutManager(mLayoutManager); rvFilterOptions.addOnItemTouchListener(new RecyclerTouchListener(getActivity(), rvFilterOptions, new RecyclerTouchListener.ClickListener() { @Override public void onClick(View view, int position) { // Perform click operation and you can get post item from array using position } @Override public void onLongClick(View view, int position) { // Perform Long click operation } }));
Note : Concept is taken from LINK
回答3:
This is simplest implementation but this will be inside recyclerviews adapter. If you want to get row item clicklistener in activity then use Interface.
public class PostRecyclerAdapter extends RecyclerView.Adapter<PostRecyclerAdapter.ViewHolder> { private Context context; private List<Post> mDataset; public static class ViewHolder extends RecyclerView.ViewHolder implements View.OnCreateContextMenuListener { public LinearLayout mainLayout; public TextView username; public ImageView image; public View mRowItem; public ViewHolder(LinearLayout view) { super(view); view.setOnCreateContextMenuListener(this); mRowItem = view; mainLayout = (LinearLayout) view.findViewById(R.id.main_view); username = (TextView) view.findViewById(R.id.username); image = (ImageView) view.findViewById(R.id.image); } } public PostRecyclerAdapter(Context context, List<Post> myDataset) { this.context = context; this.mDataset = myDataset; } @Override public PostRecyclerAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.post_layout, parent, false); ViewHolder vh = new ViewHolder((LinearLayout) view); return vh; } @Override public void onBindViewHolder(ViewHolder holder, int position) { Post postItem = mDataset.get(position); holder.username.setText(postItem.getUserame()); //Whole row item holder.mRowItem.setTag(position); holder.mRowItem.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { int pos = (int) v.getTag(); // handle your row item click. } }); } @Override public int getItemCount() { return mDataset.size(); } }