onClickListener in RecyclerView adapter?

2019-06-08 04:35发布

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();
    }

}

3条回答
乱世女痞
2楼-- · 2019-06-08 05:26

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

查看更多
Rolldiameter
3楼-- · 2019-06-08 05:26

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();
    }

}
查看更多
仙女界的扛把子
4楼-- · 2019-06-08 05:28

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

查看更多
登录 后发表回答