为什么RecyclerView没有onItemClickListener()? [英] Why doesn't RecyclerView have onItemClickListener()?

查看:70
本文介绍了为什么RecyclerView没有onItemClickListener()?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在探索 RecyclerView ,我很惊讶地看到 RecyclerView 没有 onItemClickListener()。因为 RecyclerView extends

I was exploring RecyclerView and I was surprised to see that RecyclerView does not have onItemClickListener(). Because RecyclerView extends


android.view.ViewGroup

ListView extends


android.widget.AbsListView

。但是我通过在我的 RecyclerView.Adapter 中写 onClick 解决了我的问题:

. However I solved my problem by writing onClick in my RecyclerView.Adapter:

public static class ViewHolder extends RecyclerView.ViewHolder implements OnClickListener {

    public TextView txtViewTitle;
    public ImageView imgViewIcon;

    public ViewHolder(View itemLayoutView) {
        super(itemLayoutView);
        txtViewTitle = (TextView) itemLayoutView.findViewById(R.id.item_title);
        imgViewIcon = (ImageView) itemLayoutView.findViewById(R.id.item_icon);
    }

    @Override
    public void onClick(View v) {

    }
}

但我仍然想知道谷歌为何删除 onItemClickListener()

But still I want to know why Google removed onItemClickListener()?

是否存在性能问题?

推荐答案

tl; dr 2016 使用RxJava和PublishSubject公开点击的Observable。

tl;dr 2016 Use RxJava and a PublishSubject to expose an Observable for the clicks.

public class ReactiveAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> {
    String[] mDataset = { "Data", "In", "Adapter" };

    private final PublishSubject<String> onClickSubject = PublishSubject.create();

    @Override 
    public void onBindViewHolder(final ViewHolder holder, int position) {
        final String element = mDataset[position];

        holder.itemView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
               onClickSubject.onNext(element);
            }
        });
    }

    public Observable<String> getPositionClicks(){
        return onClickSubject.asObservable();
    }
}

原帖:

由于引入了 ListView onItemClickListener 一直存在问题。当你有任何内部元素的点击监听器的那一刻,回调就不会被触发但是没有得到通知或记录良好(如果有的话)所以存在很多混淆和SO问题。

Since the introduction of ListView, onItemClickListener has been problematic. The moment you have a click listener for any of the internal elements the callback would not be triggered but it wasn't notified or well documented (if at all) so there was a lot of confusion and SO questions about it.

鉴于 RecyclerView 更进一步,没有行/列的概念,而是任意放置除了孩子的数量,他们已经将onClick委托给他们每个人,或者程序员实施。

Given that RecyclerView takes it a step further and doesn't have a concept of a row/column, but rather an arbitrarily laid out amount of children, they have delegated the onClick to each one of them, or to programmer implementation.

想想 Recyclerview 不是 ListView 1:1替换,而是作为复杂用例的更灵活的组件。正如你所说,你的解决方案是谷歌对你的期望。现在你有一个适配器,可以将onClick委托给在构造函数上传递的接口,这是 ListView Recyclerview

Think of Recyclerview not as a ListView 1:1 replacement but rather as a more flexible component for complex use cases. And as you say, your solution is what google expected of you. Now you have an adapter who can delegate onClick to an interface passed on the constructor, which is the correct pattern for both ListView and Recyclerview.

public static class ViewHolder extends RecyclerView.ViewHolder implements OnClickListener {

    public TextView txtViewTitle;
    public ImageView imgViewIcon;
    public IMyViewHolderClicks mListener;

    public ViewHolder(View itemLayoutView, IMyViewHolderClicks listener) {
        super(itemLayoutView);
        mListener = listener;
        txtViewTitle = (TextView) itemLayoutView.findViewById(R.id.item_title);
        imgViewIcon = (ImageView) itemLayoutView.findViewById(R.id.item_icon);
        imgViewIcon.setOnClickListener(this);
        itemLayoutView.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        if (v instanceof ImageView){
           mListener.onTomato((ImageView)v);
        } else {
           mListener.onPotato(v);
        }
    }

    public static interface IMyViewHolderClicks {
        public void onPotato(View caller);
        public void onTomato(ImageView callerImage);
    }

}

然后在您的适配器上

public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> {

   String[] mDataset = { "Data" };

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

       MyAdapter.ViewHolder vh = new ViewHolder(v, new MyAdapter.ViewHolder.IMyViewHolderClicks() { 
           public void onPotato(View caller) { Log.d("VEGETABLES", "Poh-tah-tos"); };
           public void onTomato(ImageView callerImage) { Log.d("VEGETABLES", "To-m8-tohs"); }
        });
        return vh;
    }

    // Replace the contents of a view (invoked by the layout manager) 
    @Override 
    public void onBindViewHolder(ViewHolder holder, int position) {
        // Get element from your dataset at this position 
        // Replace the contents of the view with that element 
        // Clear the ones that won't be used
        holder.txtViewTitle.setText(mDataset[position]);
    } 

    // Return the size of your dataset (invoked by the layout manager) 
    @Override 
    public int getItemCount() { 
        return mDataset.length;
    } 
  ...

现在查看最后一段代码: onCreateViewHolder(ViewGroup parent,int viewType)签名已经建议了不同的视图类型。对于它们中的每一个,您也需要不同的视图持有者,并且随后每个视图持有者可以具有不同的点击集。或者你可以创建一个通用的视图,它可以获取任何视图和一个 onClickListener 并相应地应用。或者将一个级别委派给协调器,以便多个片段/活动具有相同的列表,具有不同的单击行为。同样,所有的灵活性都在您身边。

Now look into that last piece of code: onCreateViewHolder(ViewGroup parent, int viewType) the signature already suggest different view types. For each one of them you'll require a different viewholder too, and subsequently each one of them can have a different set of clicks. Or you can just create a generic viewholder that takes any view and one onClickListener and applies accordingly. Or delegate up one level to the orchestrator so several fragments/activities have the same list with different click behaviour. Again, all flexibility is on your side.

这是一个非常需要的组件,与我们对 ListView的内部实现和改进非常接近直到现在。谷歌最终承认这一点很好。

It is a really needed component and fairly close to what our internal implementations and improvements to ListView were until now. It's good that Google finally acknowledges it.

这篇关于为什么RecyclerView没有onItemClickListener()?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆