有人使用RecyclerView找到了一种方法来设置一个onClickListener的项目在RecyclerView? 我想设置一个监听器为每个项目的布局,但这似乎有点太麻烦了 我确信有一种方法让RecyclerView监听onClick事件,但我不能完全弄清楚。


当前回答

很简单,添加这个类:

public class OnItemClickListener implements View.OnClickListener {
    private int position;
    private OnItemClickCallback onItemClickCallback;

    public OnItemClickListener(int position, OnItemClickCallback onItemClickCallback) {
        this.position = position;
        this.onItemClickCallback = onItemClickCallback;
    }

    @Override
    public void onClick(View view) {
        onItemClickCallback.onItemClicked(view, position);
    }

    public interface OnItemClickCallback {
        void onItemClicked(View view, int position);
    }
}

获取一个'OnItemClickCallback'接口实例,并把它放在你的activity或fragment中:

private OnItemClickListener.OnItemClickCallback onItemClickCallback = new OnItemClickListener.OnItemClickCallback() {
    @Override
    public void onItemClicked(View view, int position) {
    }
};

然后,将这个回调传递给你的recyclerView:

recyclerView.setAdapter(new SimpleStringRecyclerViewAdapter(Arrays.asList("1", "2", "3"), onItemClickCallback));

最后,这将是你的适配器:

public class SimpleStringRecyclerViewAdapter extends RecyclerView.Adapter<SimpleStringRecyclerViewAdapter.ViewHolder> {
    private List<String> mValues;
    private OnItemClickListener.OnItemClickCallback onItemClickCallback;

    public SimpleStringRecyclerViewAdapter(List<String> items, OnItemClickListener.OnItemClickCallback onItemClickCallback) {
        mValues = items;
        this.onItemClickCallback = onItemClickCallback;
    }

    public static class ViewHolder extends RecyclerView.ViewHolder {
        public final TextView mTextView;

        public ViewHolder(View view) {
            super(view);
            mTextView = (TextView) view.findViewById(R.id.txt_title);
        }
    }

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

    @Override
    public void onBindViewHolder(final ViewHolder holder, final int position) {
        holder.mTextView.setText(mValues.get(position));
        holder.mTextView.setOnClickListener(new OnItemClickListener(position, onItemClickCallback));
    }

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

其他回答

你可以实现View。OnClickListener到你的ViewHolder类

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

和onBindViewHolder设置你的视图持有人的项目:

public void onBindViewHolder(ViewHolder holder, int position) {
    holder.tvTitle.setText(objects.get(position).getTitle());
    holder.item = objects.get(position);
}

这对我来说很难在活动中有一个项目点击监听器,也有一个项目的单一视图的点击监听器,不会触发项目点击监听器。在玩了Jacob Tabak的回答后,我尊重他的回答,如果项目内没有其他触摸操作,就点击项目。

我有一个自定义OnClickListener接口,有一个项目点击事件,它持有从适配器点击的项目的视图和项目的位置。我在构造函数(或者它可以是setter)中呈现它的一个实例,并将它附加到视图持有者容器click listener。

我也有其他的点击监听器在适配器(可以在视图持有人),这将处理当前的视图点击从容器。

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

    final MyViewHolder viewHolder = new MyViewHolder(layoutView);

    viewHolder.container.setOnClickListener(new OnClickListener() {

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

    viewHоlder.button.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View v) {
            //do button click work here with
            // mData.get( viewHolder.getAdapterPosition() );
        }
    });

    return viewHolder;
}

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

在活动中,您需要通过传递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);
}

还有我的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);
}}

下面是我的代码片段:

v.setOnClickListener(new OnClickListener() {
    @Override
    public void onClick(View v) {
        int newPosition = MainActivity.mRecyclerView.getChildAdapterPosition(v);
        Intent cardViewIntent = new Intent(c, MainActivityCards.class);
        cardViewIntent.putExtra("Position", newPosition);
        c.startActivity(cardViewIntent);
    }
});

v是onCreateViewHolder的视图 c为背景信息

这是我的自定义适配器的完整代码,这段代码将用XML文件“list_item”中定义的列表项膨胀行,它还将在具有各自位置的所有列表项行上执行单击事件。

public class MyCustomAdapter extends RecyclerView.Adapter`<`AdapterMyCustomAdapter.ViewHolder> {

    public static class ViewHolder extends RecyclerView.ViewHolder implements OnClickListener {
        public onItemClickListener mListener;
        public ViewHolder(View v, onItemClickListener listener) {
            super(v);
            mListener =listener;
            v.setOnClickListener(this);
        }

        @Override
        public void onClick(View v) {
            mListener.onRecyclerItemClick(v, getPosition());
        }

        public static interface onItemClickListener {
            public void onRecyclerItemClick(View view , int position);
        }
    }

    @Override
    public int getItemCount() {
        return 5;
    }

    @Override
    public void onBindViewHolder(ViewHolder holder, int pos) {      

    }

    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int position) {
        View v = LayoutInflater.from(parent.getContext())
                .inflate(R.layout.list_item, parent, false);

    /* here list_item is an xml file we want to inflate ...it is same as we do in case of listview for customization.*/

        MyCustomAdapter.ViewHolder vh = new ViewHolder(v, new MyCustomAdapter.ViewHolder.onItemClickListener() {

            @Override
            public void onRecyclerItemClick(View view, int position) {
                System.out.println("clicked on list item at position " +position);
            } 
        });
        return vh;
    }
}

如果你想在个别项目上捕捉点击事件,那么只需在ViewHolder类中实现OnClickListener,然后在个别视图或整个itemView上设置点击侦听器。

下面的例子说明了同样的情况

public  class ContactViewHolder extends RecyclerView.ViewHolder implements OnClickListener
    {
        TextView txt_title,txt_name,txt_email;

        public ContactViewHolder(View itemView) 
        {
            super(itemView);
            txt_title = (TextView)itemView.findViewById(R.id.txt_title);
            txt_name  = (TextView)itemView.findViewById(R.id.txt_name);
            txt_email = (TextView)itemView.findViewById(R.id.txt_email);

            txt_name.setOnClickListener(this);
            txt_email.setOnClickListener(this);
            itemView.setOnClickListener(this);
        }

        @Override
        public void onClick(View v) {
            // TODO Auto-generated method stub

            if(v == itemView)
            {
                Toast.makeText(RecyclerDemoActivity.this, "Visiting Card Clicked is ==>"+txt_name.getText(), Toast.LENGTH_SHORT).show();
            }

            if(v == txt_name)
            {
                Toast.makeText(RecyclerDemoActivity.this, "Name ==>"+txt_name.getText(), Toast.LENGTH_SHORT).show();
            }

            if(v == txt_email)
            {
                Toast.makeText(RecyclerDemoActivity.this, "Email ==>"+txt_email.getText(), Toast.LENGTH_SHORT).show();
            }
        }

    }
}