RecyclerView onClick

2018-12-30 23:48发布

Has anyone using RecyclerView found a way to set an onClickListener to items in the RecyclerView? I thought of setting a listener to each of the layouts for each item but that seems a little too much hassle I'm sure there is a way for the RecyclerView to listen for the onClick event but I can't quite figure it out.

30条回答
千与千寻千般痛.
2楼-- · 2018-12-31 00:23

This was so hard for me to have on item click listener in the activity and also to have click listener for single view of the item that will not trigger on item click listener. After playing around with Jacob Tabak's answer I respect his answer for on item click if no other touch actions inside item are presented.

I have a custom OnClickListener interface that have on item click event which holds the clicked item's view and the item position from the adapter. I present an instance of it in the constructor(or it can be with setter) and attach it to the view holder container click listener.

I also have other click listener in the Adapter(Can be in the view holder) which will handle current View click from the container.

 public class MyRecyclerAdapter extends RecyclerView.Adapter<MyViewHolder> {

private ArrayList<String> mData;
private OnItemClickListener mOnItemClickListener;

public interface OnItemClickListener {
    public void onItemClick(View view, int position);
}

public MyRecyclerAdapter(ArrayList<String> itemsData,
        OnItemClickListener onItemClickListener) {
    mOnItemClickListener = onItemClickListener;
    this.mData = itemsData;
}

@Override
public MyViewHolder onCreateViewHolder(ViewGroup parent,
        int viewType) {

    View layoutView = LayoutInflater.from(mContext).inflate(
            R.layout.list_item, parent, false);

    MyViewHolder viewHolder = new MyViewHolder(layoutView);

    return viewHolder;
}

@Override
public void onBindViewHolder(MyViewHolder viewHolder,
        final int position) {

        viewHolder.container.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                mOnItemClickListener.onItemClick(v, position);
            }
        });

        viewHilder.button.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                //do button click work here
            }
        });

}

@Override
public int getItemCount() {
    return mData.size();
}}

In the activity you need to initialize the adapter by passing instance of the OnItemClickListener

public class FeedActivity extends ActionBarActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    ...

    RecyclerView recyclerView = (RecyclerView) findViewById(R.id.my_recycler_view);

    .....

    MyRecyclerAdapter adapter = new MyRecyclerAdapter(new ArrayList<String>(), new OnItemClickListener() {

        @Override
        public void onItemClick(View view, int position) {

            ///list item was clicked
        }
    });

    recyclerView.setLayoutManager(new LinearLayoutManager(this));
    recyclerView.setAdapter(mFeedsAdapter);
}

And my ViewHolder

public class MyViewHolder extends RecyclerView.ViewHolder {

public Button button;
public View container;

public MyViewHolder(View itemLayoutView) {
    super(itemLayoutView);

    container = itemLayoutView;
    button = (Button) itemLayoutView.findViewById(R.id.button);
}}
查看更多
流年柔荑漫光年
3楼-- · 2018-12-31 00:25

You can implement OnClickListener to your ViewHolder class

public static class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
        public Item item
        @InjectView(R.id.tv_title)
        public TextView tvTitle;
        @InjectView(R.id.rl_row)
        public RelativeLayout rlRow;

        public ViewHolder(View v) {
            super(v);
            ButterKnife.inject(this, v);
            v.setOnClickListener(this);
        }

        @Override
        public void onClick(View view) {
            Log.e("item title",item.getTitle());
        }
    }

And onBindViewHolder set your view holder's item

public void onBindViewHolder(ViewHolder holder, int position) {
        holder.tvTitle.setText(objects.get(position).getTitle());
        holder.item = objects.get(position);
        }
查看更多
余欢
4楼-- · 2018-12-31 00:25

For me the clean way to do that is this one.

  • Adapter constructor

    `private class EnvironmentTypeRecyclerViewAdapter extends RecyclerView.Adapter {

    private final EnvironmentTypeRecyclerViewAdapterListener mEnvironmentTypeRecyclerViewAdapterListener;
    private List<Environment> mEnvironmentsData;
    
    
    public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener
    {
    
        public ViewHolder(View v)
        {
            super(v);
            v.setOnClickListener(this);
    
        }
    
        @Override
        public void onClick(View v)
        {
    
            Environment environment = mEnvironmentsData.get(getAdapterPosition());
            if (mEnvironmentTypeRecyclerViewAdapterListener != null && environment != null)
            {
                mEnvironmentTypeRecyclerViewAdapterListener.onListItemSelected(environment);
            }
        }
    }
    
    public EnvironmentTypeRecyclerViewAdapter(List<SmallCellEnvironment> environments, EnvironmentTypeRecyclerViewAdapterListener environmentTypeRecyclerViewAdapterListener)
    {
        mEnvironmentTypeRecyclerViewAdapterListener = environmentTypeRecyclerViewAdapterListener;
        mEnvironmentsData = environments;
    }`
    

The Linked Interface

private interface EnvironmentTypeRecyclerViewAdapterListener
{
    void onListItemSelected(Environment environment);
}
查看更多
像晚风撩人
5楼-- · 2018-12-31 00:27

As the API's have radically changed, It wouldn't surprise me if you were to create an OnClickListener for each item. It isn't that much of a hassle though. In your implementation of RecyclerView.Adapter<MyViewHolder>, you should have:

private final OnClickListener mOnClickListener = new MyOnClickListener();

@Override
public MyViewHolder onCreateViewHolder(final ViewGroup parent, final int viewType) {
    View view = LayoutInflater.from(mContext).inflate(R.layout.myview, parent, false);
    view.setOnClickListener(mOnClickListener);
    return new MyViewHolder(view);
}

The onClick method:

@Override
public void onClick(final View view) {
    int itemPosition = mRecyclerView.getChildLayoutPosition(view);
    String item = mList.get(itemPosition);
    Toast.makeText(mContext, item, Toast.LENGTH_LONG).show();
}
查看更多
何处买醉
6楼-- · 2018-12-31 00:27

Check out a similar question @CommonsWare's comment links to this, which implements the OnClickListener interface in the viewHolder.

Here's a simple example of the ViewHolder:

    TextView textView;//declare global with in adapter class

public static class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {

      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++){

        }


      }
  }

The Adapter then looks like this:

    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view =LayoutInflater.from(parent.getContext()).inflate(android.R.layout.simple_list_item_1, parent, false);

        return new ViewHolder(view);
    }
查看更多
余生请多指教
7楼-- · 2018-12-31 00:27

you can easily define setOnClickListener in your ViewHolder class as follow :

public class ViewHolder extends RecyclerView.ViewHolder {
    TextView product_name;

    ViewHolder(View itemView) {
        super(itemView);
        product_name = (TextView) itemView.findViewById(R.id.product_name);
        itemView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                int itemPosition = getLayoutPosition();
                Toast.makeText(getApplicationContext(), itemPosition + ":" + String.valueOf(product_name.getText()), Toast.LENGTH_SHORT).show();
            }
        });
    }
}
查看更多
登录 后发表回答