1021

我正在探索RecyclerView,我很惊讶地发现RecyclerView没有onItemClickListener()

我有两个问题。

主要问题

我想知道为什么谷歌删除了onItemClickListener()

是否存在性能问题或其他问题?

次要问题

我通过写我的解决了我的onClick问题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) {

    }
}

这可以吗/有没有更好的方法?

4

31 回答 31

1236

tl;dr 2016使用 RxJava 和 PublishSubject 为点击公开一个 Observable。

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

原帖:

自推出以来ListViewonItemClickListener一直存在问题。当您拥有任何内部元素的点击侦听器时,不会触发回调,但没有通知或没有充分记录(如果有的话),因此存在很多混淆和 SO 问题。

鉴于这RecyclerView更进一步,并且没有行/列的概念,而是任意布局的孩子数量,他们将 onClick 委托给每个孩子,或委托给程序员实现。

不要Recyclerview将其视为ListView1:1 的替代品,而是将其视为复杂用例的更灵活的组件。正如你所说,你的解决方案是谷歌对你的期望。现在您有了一个适配器,它可以将 onClick 委托给构造函数中传递的接口,这对于ListView和都是正确的模式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并相应地应用。或者将一个级别委托给协调器,以便多个片段/活动具有相同的列表和不同的点击行为。同样,所有灵活性都在您身边。

它是一个真正需要的组件,并且非常接近我们ListView迄今为止的内部实现和改进。谷歌终于承认了这一点,这很好。

于 2014-07-24T12:00:40.327 回答
125

为什么 RecyclerView 没有onItemClickListener

RecyclerView是一个工具箱,与旧的相比,ListView它具有更少的内置功能和更大的灵活性。这onItemClickListener不是从 ListView 中删除的唯一功能。但是它有很多听众和方法可以根据你的喜好扩展它,它在右手中要强大得多;)。

在我看来,删除的最复杂的功能RecyclerViewFast Scroll。大多数其他功能都可以轻松地重新实现。

如果您想知道RecyclerView添加了哪些其他很酷的功能,请阅读另一个问题答案。

内存高效 - onItemClickListener 的插入式解决方案

这个解决方案是由Android GDE的Hugo Visser在发布后提出的。他为您提供了一个免许可证课程,您只需放入您的代码并使用它。RecyclerView

它展示了RecyclerView通过使用RecyclerView.OnChildAttachStateChangeListener.

编辑 2019:我的 kotlin 版本,java 版本,来自 Hugo Visser,保留在下面

科特林/Java

创建一个文件values/ids.xml并将其放入其中:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <item name="item_click_support" type="id" />
</resources>

然后将下面的代码添加到您的源

科特林

用法:

recyclerView.onItemClick { recyclerView, position, v ->
    // do it
}

(它还支持长项目点击,我添加的另一个功能见下文)。

实现(我对 Hugo Visser Java 代码的改编):

typealias OnRecyclerViewItemClickListener = (recyclerView: RecyclerView, position: Int, v: View) -> Unit
typealias OnRecyclerViewItemLongClickListener = (recyclerView: RecyclerView, position: Int, v: View) -> Boolean

class ItemClickSupport private constructor(private val recyclerView: RecyclerView) {

    private var onItemClickListener: OnRecyclerViewItemClickListener? = null
    private var onItemLongClickListener: OnRecyclerViewItemLongClickListener? = null

    private val attachListener: RecyclerView.OnChildAttachStateChangeListener = object : RecyclerView.OnChildAttachStateChangeListener {
        override fun onChildViewAttachedToWindow(view: View) {
            // every time a new child view is attached add click listeners to it
            val holder = this@ItemClickSupport.recyclerView.getChildViewHolder(view)
                    .takeIf { it is ItemClickSupportViewHolder } as? ItemClickSupportViewHolder

            if (onItemClickListener != null && holder?.isClickable != false) {
                view.setOnClickListener(onClickListener)
            }
            if (onItemLongClickListener != null && holder?.isLongClickable != false) {
                view.setOnLongClickListener(onLongClickListener)
            }
        }

        override fun onChildViewDetachedFromWindow(view: View) {

        }
    }

    init {
        // the ID must be declared in XML, used to avoid
        // replacing the ItemClickSupport without removing
        // the old one from the RecyclerView
        this.recyclerView.setTag(R.id.item_click_support, this)
        this.recyclerView.addOnChildAttachStateChangeListener(attachListener)
    }

    companion object {
        fun addTo(view: RecyclerView): ItemClickSupport {
            // if there's already an ItemClickSupport attached
            // to this RecyclerView do not replace it, use it
            var support: ItemClickSupport? = view.getTag(R.id.item_click_support) as? ItemClickSupport
            if (support == null) {
                support = ItemClickSupport(view)
            }
            return support
        }

        fun removeFrom(view: RecyclerView): ItemClickSupport? {
            val support = view.getTag(R.id.item_click_support) as? ItemClickSupport
            support?.detach(view)
            return support
        }
    }

    private val onClickListener = View.OnClickListener { v ->
        val listener = onItemClickListener ?: return@OnClickListener
        // ask the RecyclerView for the viewHolder of this view.
        // then use it to get the position for the adapter
        val holder = this.recyclerView.getChildViewHolder(v)
        listener.invoke(this.recyclerView, holder.adapterPosition, v)
    }

    private val onLongClickListener = View.OnLongClickListener { v ->
        val listener = onItemLongClickListener ?: return@OnLongClickListener false
        val holder = this.recyclerView.getChildViewHolder(v)
        return@OnLongClickListener listener.invoke(this.recyclerView, holder.adapterPosition, v)
    }

    private fun detach(view: RecyclerView) {
        view.removeOnChildAttachStateChangeListener(attachListener)
        view.setTag(R.id.item_click_support, null)
    }

    fun onItemClick(listener: OnRecyclerViewItemClickListener?): ItemClickSupport {
        onItemClickListener = listener
        return this
    }

    fun onItemLongClick(listener: OnRecyclerViewItemLongClickListener?): ItemClickSupport {
        onItemLongClickListener = listener
        return this
    }

}

/** Give click-ability and long-click-ability control to the ViewHolder */
interface ItemClickSupportViewHolder {
    val isClickable: Boolean get() = true
    val isLongClickable: Boolean get() = true
}

// Extension function
fun RecyclerView.addItemClickSupport(configuration: ItemClickSupport.() -> Unit = {}) = ItemClickSupport.addTo(this).apply(configuration)

fun RecyclerView.removeItemClickSupport() = ItemClickSupport.removeFrom(this)

fun RecyclerView.onItemClick(onClick: OnRecyclerViewItemClickListener) {
    addItemClickSupport { onItemClick(onClick) }
}
fun RecyclerView.onItemLongClick(onLongClick: OnRecyclerViewItemLongClickListener) {
    addItemClickSupport { onItemLongClick(onLongClick) }
}

(请记住,您还需要添加一个 XML 文件,请参阅本节上方)

Kotlin 版本的额外功能

有时您不希望 RecyclerView 的所有项目都是可点击的。

为了解决这个问题,我介绍了ItemClickSupportViewHolder您可以ViewHolder用来控制可点击项目的界面。

例子:

class MyViewHolder(view): RecyclerView.ViewHolder(view), ItemClickSupportViewHolder {
    override val isClickable: Boolean get() = false
    override val isLongClickable: Boolean get() = false
}

爪哇

用法:

ItemClickSupport.addTo(mRecyclerView)
        .setOnItemClickListener(new ItemClickSupport.OnItemClickListener() {
    @Override
    public void onItemClicked(RecyclerView recyclerView, int position, View v) {
        // do it
    }
});

(它也支持长项目点击)

实施(我添加的评论):

public class ItemClickSupport {
    private final RecyclerView mRecyclerView;
    private OnItemClickListener mOnItemClickListener;
    private OnItemLongClickListener mOnItemLongClickListener;
    private View.OnClickListener mOnClickListener = new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            if (mOnItemClickListener != null) {
                // ask the RecyclerView for the viewHolder of this view.
                // then use it to get the position for the adapter
                RecyclerView.ViewHolder holder = mRecyclerView.getChildViewHolder(v);
                mOnItemClickListener.onItemClicked(mRecyclerView, holder.getAdapterPosition(), v);
            }
        }
    };
    private View.OnLongClickListener mOnLongClickListener = new View.OnLongClickListener() {
        @Override
        public boolean onLongClick(View v) {
            if (mOnItemLongClickListener != null) {
                RecyclerView.ViewHolder holder = mRecyclerView.getChildViewHolder(v);
                return mOnItemLongClickListener.onItemLongClicked(mRecyclerView, holder.getAdapterPosition(), v);
            }
            return false;
        }
    };
    private RecyclerView.OnChildAttachStateChangeListener mAttachListener
            = new RecyclerView.OnChildAttachStateChangeListener() {
        @Override
        public void onChildViewAttachedToWindow(View view) {
            // every time a new child view is attached add click listeners to it
            if (mOnItemClickListener != null) {
                view.setOnClickListener(mOnClickListener);
            }
            if (mOnItemLongClickListener != null) {
                view.setOnLongClickListener(mOnLongClickListener);
            }
        }

        @Override
        public void onChildViewDetachedFromWindow(View view) {

        }
    };

    private ItemClickSupport(RecyclerView recyclerView) {
        mRecyclerView = recyclerView;
        // the ID must be declared in XML, used to avoid
        // replacing the ItemClickSupport without removing
        // the old one from the RecyclerView
        mRecyclerView.setTag(R.id.item_click_support, this);
        mRecyclerView.addOnChildAttachStateChangeListener(mAttachListener);
    }

    public static ItemClickSupport addTo(RecyclerView view) {
        // if there's already an ItemClickSupport attached
        // to this RecyclerView do not replace it, use it
        ItemClickSupport support = (ItemClickSupport) view.getTag(R.id.item_click_support);
        if (support == null) {
            support = new ItemClickSupport(view);
        }
        return support;
    }

    public static ItemClickSupport removeFrom(RecyclerView view) {
        ItemClickSupport support = (ItemClickSupport) view.getTag(R.id.item_click_support);
        if (support != null) {
            support.detach(view);
        }
        return support;
    }

    public ItemClickSupport setOnItemClickListener(OnItemClickListener listener) {
        mOnItemClickListener = listener;
        return this;
    }

    public ItemClickSupport setOnItemLongClickListener(OnItemLongClickListener listener) {
        mOnItemLongClickListener = listener;
        return this;
    }

    private void detach(RecyclerView view) {
        view.removeOnChildAttachStateChangeListener(mAttachListener);
        view.setTag(R.id.item_click_support, null);
    }

    public interface OnItemClickListener {

        void onItemClicked(RecyclerView recyclerView, int position, View v);
    }

    public interface OnItemLongClickListener {

        boolean onItemLongClicked(RecyclerView recyclerView, int position, View v);
    }
}

它是如何工作的(为什么它是有效的)

此类通过将 a 附加RecyclerView.OnChildAttachStateChangeListenerRecyclerView. 每次有孩子从RecyclerView. 代码使用它来将点击/长按侦听器附加到视图。该听众询问RecyclerView包含RecyclerView.ViewHolder该位置的 。

RecyclerView这比其他解决方案更有效,因为它避免为每个视图创建多个侦听器,并在滚动时不断销毁和创建它们。

如果您需要更多,您还可以调整代码以将持有人返还给您。

最后的评论

请记住,通过在列表的每个视图上设置一个单击侦听器来在适配器中处理它是完全可以的,就像其他建议的答案一样。

这不是最有效的做法(每次重用视图时都会创建一个新的侦听器),但它可以工作,并且在大多数情况下这不是问题。

这也有点反对关注点分离,因为委托点击事件并不是适配器的真正工作。

于 2016-03-10T13:12:54.473 回答
95

我喜欢这种方式,我正在使用它

里面

public Adapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType)

View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.view_image_and_text, parent, false);
v.setOnClickListener(new MyOnClickListener());

并在任何你想要的地方创建这个类

class MyOnClickListener implements View.OnClickListener {
    @Override
    public void onClick(View v) {
       int itemPosition = recyclerView.indexOfChild(v);
       Log.e("Clicked and Position is ",String.valueOf(itemPosition));
    }
}

我以前读过有更好的方法,但我喜欢这种方法简单而不复杂。

于 2015-03-19T10:22:32.517 回答
41

Android Recyclerview With onItemClickListener, 为什么我们不能尝试这个只是工作ListView

来源:链接

public class RecyclerItemClickListener implements RecyclerView.OnItemTouchListener {

private OnItemClickListener mListener;
public interface OnItemClickListener {
    public void onItemClick(View view, int position);
}
GestureDetector mGestureDetector;
public RecyclerItemClickListener(Context context, OnItemClickListener listener) {
    mListener = listener;
    mGestureDetector = new GestureDetector(context, new GestureDetector.SimpleOnGestureListener() {
        @Override
        public boolean onSingleTapUp(MotionEvent e) {
            return true;
        }
    });
}
@Override
public boolean onInterceptTouchEvent(RecyclerView view, MotionEvent e) {
    View childView = view.findChildViewUnder(e.getX(), e.getY());
    if (childView != null && mListener != null && mGestureDetector.onTouchEvent(e)) {
        mListener.onItemClick(childView, view.getChildAdapterPosition(childView));
    }
    return false;
}

@Override
public void onTouchEvent(RecyclerView view, MotionEvent motionEvent) {
}

@Override
public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {

  }
}

并将其设置为 RecyclerView:

    recyclerView = (RecyclerView)rootView. findViewById(R.id.recyclerView);
    RecyclerView.LayoutManager mLayoutManager = new            LinearLayoutManager(getActivity());
    recyclerView.setLayoutManager(mLayoutManager);
    recyclerView.addOnItemTouchListener(
            new RecyclerItemClickListener(getActivity(), new   RecyclerItemClickListener.OnItemClickListener() {
                @Override
                public void onItemClick(View view, int position) {
                    // TODO Handle item click
                    Log.e("@@@@@",""+position);
                }
            })
    );
于 2015-07-23T13:55:40.183 回答
25

感谢@marmor,我更新了我的答案。

我认为在ViewHolder类构造函数中处理 onClick() 并通过OnItemClickListener接口将其传递给父类是一个很好的解决方案。

我的适配器.java

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

private LayoutInflater layoutInflater;
private List<MyObject> items;
private AdapterView.OnItemClickListener onItemClickListener;

public MyAdapter(Context context, AdapterView.OnItemClickListener onItemClickListener, List<MyObject> items) {
    layoutInflater = LayoutInflater.from(context);
    this.items = items;
    this.onItemClickListener = onItemClickListener;
}

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

@Override
public void onBindViewHolder(ViewHolder holder, int position) {
    MyObject item = items.get(position);
}

public MyObject getItem(int position) {
    return items.get(position);
}


class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
    private TextView title;
    private ImageView avatar;

    public ViewHolder(View itemView) {
        super(itemView);
        title = itemView.findViewById(R.id.title);
        avatar = itemView.findViewById(R.id.avatar);

        title.setOnClickListener(this);
        avatar.setOnClickListener(this);
        itemView.setOnClickListener(this);
    }

    @Override
    public void onClick(View view) {
        //passing the clicked position to the parent class
        onItemClickListener.onItemClick(null, view, getAdapterPosition(), view.getId());
    }
}
}

其他类中适配器的使用:

MyFragment.java

public class MyFragment extends Fragment implements AdapterView.OnItemClickListener {

private RecyclerView recycleview;
private MyAdapter adapter;

    .
    .
    .

private void init(Context context) {
    //passing this fragment as OnItemClickListener to the adapter
    adapter = new MyAdapter(context, this, items);
    recycleview.setAdapter(adapter);
}

@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
    //you can get the clicked item from the adapter using its position
    MyObject item = adapter.getItem(position);

    //you can also find out which view was clicked
    switch (view.getId()) {
        case R.id.title:
            //title view was clicked
            break;
        case R.id.avatar:
            //avatar view was clicked
            break;
        default:
            //the whole row was clicked
    }
}

}
于 2015-04-24T07:58:08.900 回答
22

伙计们在您的主要活动中使用此代码。非常有效的方法

RecyclerView recyclerView = (RecyclerView) findViewById(R.id.users_list);            
UsersAdapter adapter = new UsersAdapter(users, this);
recyclerView.setAdapter(adapter);
adapter.setOnCardClickListner(this);

这是您的适配器类。

public class UsersAdapter extends RecyclerView.Adapter<UsersAdapter.UserViewHolder> {
        private ArrayList<User> mDataSet;
        OnCardClickListner onCardClickListner;


        public UsersAdapter(ArrayList<User> mDataSet) {
            this.mDataSet = mDataSet;
        }

        @Override
        public UserViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
            View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.user_row_layout, parent, false);
            UserViewHolder userViewHolder = new UserViewHolder(v);
            return userViewHolder;
        }

        @Override
        public void onBindViewHolder(UserViewHolder holder, final int position) {
            holder.name_entry.setText(mDataSet.get(position).getUser_name());
            holder.cardView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    onCardClickListner.OnCardClicked(v, position);
                }
            });
        }

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

        @Override
        public void onAttachedToRecyclerView(RecyclerView recyclerView) {
            super.onAttachedToRecyclerView(recyclerView);
        }


        public static class UserViewHolder extends RecyclerView.ViewHolder {
            CardView cardView;
            TextView name_entry;

            public UserViewHolder(View itemView) {
                super(itemView);
                cardView = (CardView) itemView.findViewById(R.id.user_layout);
                name_entry = (TextView) itemView.findViewById(R.id.name_entry);
             }
        }

        public interface OnCardClickListner {
            void OnCardClicked(View view, int position);
        }

        public void setOnCardClickListner(OnCardClickListner onCardClickListner) {
            this.onCardClickListner = onCardClickListner;
        }
    }

在此之后,您将在您的活动中获得此覆盖方法。

@Override
    public void OnCardClicked(View view, int position) {
        Log.d("OnClick", "Card Position" + position);
    }
于 2016-03-09T12:04:38.823 回答
21

> RecyclerView 与 Listview 有何不同?

一个区别是LayoutManagerRecyclerView 有一个类,您可以通过它管理您的喜欢RecyclerView-

水平或垂直滚动LinearLayoutManager

网格布局由GridLayoutManager

交错的 GridLayout 由StaggeredGridLayoutManager

就像 RecyclerView 的水平滚动一样-

LinearLayoutManager llm = new LinearLayoutManager(context);
llm.setOrientation(LinearLayoutManager.HORIZONTAL);
recyclerView.setLayoutManager(llm);
于 2014-12-26T06:27:47.220 回答
15

如何将它们放在一起示例...

  • onClick() 处理
  • 光标 - RecyclerView
  • ViewHolder 类型

    public class OrderListCursorAdapter extends CursorRecyclerViewAdapter<OrderListCursorAdapter.ViewHolder> {
    
    private static final String TAG = OrderListCursorAdapter.class.getSimpleName();
    private static final int ID_VIEW_HOLDER_ACTUAL = 0;
    private static final int ID_VIEW_HOLDER = 1;
    
    public OrderListCursorAdapter(Context context, Cursor cursor) {
        super(context, cursor);
    }
    
    public static class ViewHolderActual extends ViewHolder {
        private static final String TAG = ViewHolderActual.class.getSimpleName();
        protected IViewHolderClick listener;
        protected Button button;
    
        public ViewHolderActual(View v, IViewHolderClick listener) {
            super(v, listener);
            this.listener = listener;
            button = (Button) v.findViewById(R.id.orderList_item_button);
            button.setOnClickListener(this);
        }
    
        public void initFromData(OrderData data) {
            Log.d(TAG, "><initFromData(data=" + data + ")");
            orderId = data.getId();
            vAddressStart.setText(data.getAddressStart());
            vAddressEnd.setText(data.getAddressEnd());
        }
    
        @Override
        public void onClick(View view) {
            if (view instanceof Button) {
                listener.onButtonClick((Button) view, getPosition(), this);
            } else {
                super.onClick(view);
            }
        }
    
        public interface IViewHolderClick extends ViewHolder.IViewHolderClick {
            public void onButtonClick(Button button, int position, ViewHolder viewHolder);
        }
    }
    
    public static class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
        private static final String TAG = ViewHolder.class.getSimpleName();
        protected long orderId;
        protected IViewHolderClick listener;
        protected TextView vAddressStart;
        protected TextView vAddressEnd;
        protected TextView vStatus;
    
        public ViewHolder(View v, IViewHolderClick listener) {
            super(v);
            this.listener = listener;
            v.setOnClickListener(this);
    
            vAddressStart = (TextView) v.findViewById(R.id.addressStart);
            vAddressEnd = (TextView) v.findViewById(R.id.addressEnd);
            vStatus = (TextView) v.findViewById(R.id.status);
        }
    
        public void initFromData(OrderData data) {
            Log.d(TAG, "><initFromData(data=" + data + ")");
            orderId = data.getId();
            vAddressStart.setText(data.getAddressStart());
            vAddressEnd.setText(data.getAddressEnd());
        }
    
        public long getOrderId() {
            return orderId;
        }
    
        @Override
        public void onClick(View view) {
            listener.onCardClick(view, getPosition(), this);
        }
    
        public interface IViewHolderClick {
            public void onCardClick(View view, int position, ViewHolder viewHolder);
        }
    }
    
    @Override
    public int getItemViewType(int position) {
        return position == 0 ? ID_VIEW_HOLDER_ACTUAL : ID_VIEW_HOLDER;
    }
    
    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        Log.d(TAG, ">>onCreateViewHolder(parent=" + parent + ", viewType=" + viewType + ")");
    
        ViewHolder result;
    
        switch (viewType) {
            case ID_VIEW_HOLDER_ACTUAL: {
                View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.card_layout_actual, parent, false);
                result = new ViewHolderActual(itemView, new ViewHolderActual.IViewHolderClick() {
                    @Override
                    public void onCardClick(View view, int position, ViewHolder viewHolder) {
                        Log.d(TAG, "><onCardClick(view=" + view + ", position=" + position + ", viewHolder=" + viewHolder + ")");
                        Intent intent = new Intent(view.getContext(), OrderDetailActivity.class);
                        intent.putExtra(OrderDetailActivity.ARG_ORDER_ID, viewHolder.getOrderId());
                        view.getContext().startActivity(intent);
                    }
    
                    @Override
                    public void onButtonClick(Button button, int position, ViewHolder viewHolder) {
                        Log.d(TAG, "><onButtonClick(button=" + button + ", position=" + position + ", viewHolder=" + viewHolder + ")");
                        Intent intent = new Intent(button.getContext(), OrderMapActivity.class);
                        intent.putExtra(OrderMapActivity.ARG_ORDER_ID, viewHolder.getOrderId());
                        button.getContext().startActivity(intent);
                    }
                });
                break;
            }
            case ID_VIEW_HOLDER:
            default: {
                View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.card_layout, parent, false);
                result = new ViewHolder(itemView, new ViewHolder.IViewHolderClick() {
                    @Override
                    public void onCardClick(View view, int position, ViewHolder viewHolder) {
                        Log.d(TAG, "><onCardClick(view=" + view + ", position=" + position + ", viewHolder=" + viewHolder + ")");
                        Intent intent = new Intent(view.getContext(), OrderDetailActivity.class);
                        intent.putExtra(OrderDetailActivity.ARG_ORDER_ID, viewHolder.getOrderId());
                        view.getContext().startActivity(intent);
                    }
                });
                break;
            }
        }
    
        Log.d(TAG, "<<onCreateViewHolder(parent=" + parent + ", viewType=" + viewType + ")= " + result);
        return result;
    }
    
    @Override
    public void onBindViewHolder(ViewHolder viewHolder, Cursor cursor) {
        Log.d(TAG, "><onBindViewHolder(viewHolder=" + viewHolder + ", cursor=" + cursor + ")");
        final OrderData orderData = new OrderData(cursor);
        viewHolder.initFromData(orderData);
    }
    }
    
于 2015-04-02T08:38:38.377 回答
15

跟进MLProgrammer-CiM优秀的RxJava方案

消费/观察点击

Consumer<String> mClickConsumer = new Consumer<String>() {
        @Override
        public void accept(@NonNull String element) throws Exception {
            Toast.makeText(getApplicationContext(), element +" was clicked", Toast.LENGTH_LONG).show();
        }
    };

ReactiveAdapter rxAdapter = new ReactiveAdapter();
rxAdapter.getPositionClicks().subscribe(mClickConsumer);

RxJava 2.+

将原来的tl;dr修改为:

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

PublishSubject#asObservable()去掉了。只需返回PublishSubjectwhich 是一个Observable.

于 2017-05-18T01:21:58.870 回答
12

据我了解MLProgrammer-CiM 答案,只需这样做:

class MyViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener{
    private ImageView image;
    private TextView title;
    private TextView price;

    public MyViewHolder(View itemView) {
        super(itemView);
        image = (ImageView)itemView.findViewById(R.id.horizontal_list_image);
        title = (TextView)itemView.findViewById(R.id.horizontal_list_title);
        price = (TextView)itemView.findViewById(R.id.horizontal_list_price);
        image.setOnClickListener(this);
        title.setOnClickListener(this);
        price.setOnClickListener(this);
    }


    @Override
    public void onClick(View v) {
        Toast.makeText(context, "Item click nr: "+getLayoutPosition(), Toast.LENGTH_SHORT).show();
    }
}
于 2015-06-22T09:54:14.373 回答
10

阅读@MLProgrammer-CiM的答案后,这是我的代码:

class NormalViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener{

    @Bind(R.id.card_item_normal)
    CardView cardView;

    public NormalViewHolder(View itemView) {
        super(itemView);
        ButterKnife.bind(this, itemView);
        cardView.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        if(v instanceof CardView) {
            // use getAdapterPosition() instead of getLayoutPosition()
            int itemPosition = getAdapterPosition();
            removeItem(itemPosition);
        }
    }
}
于 2015-08-12T08:07:32.880 回答
10

RecyclerView 没有,onItemClickListener因为 RecyclerView 负责回收视图(惊喜!),所以回收的视图负责处理它接收到的点击事件。

这实际上使它更易于使用,特别是如果您有可以在多个位置单击的项目。


无论如何,检测对 RecyclerView 项目的点击非常容易。您需要做的就是定义一个接口(如果您不使用 Kotlin,在这种情况下您只需传入一个 lambda):

public class MyAdapter extends RecyclerView.Adapter<MyViewHolder> {
    private final Clicks clicks;

    public MyAdapter(Clicks clicks) {
        this.clicks = clicks;
    }

    private List<MyObject> items = Collections.emptyList();

    public void updateData(List<MyObject> items) {
        this.items = items;
        notifyDataSetChanged(); // TODO: use ListAdapter for diffing instead if you need animations
    }

    public interface Clicks {
        void onItemSelected(MyObject myObject, int position);
    }

    public class MyViewHolder extends RecyclerView.ViewHolder {
        private MyObject myObject;    

        public MyViewHolder(View view) {
            super(view);
            // bind views
            view.setOnClickListener((v) -> {
                int adapterPosition = getAdapterPosition();
                if(adapterPosition >= 0) {
                    clicks.onItemSelected(myObject, adapterPosition);
                }
            });
        }

        public void bind(MyObject myObject) {
            this.myObject = myObject;
            // bind data to views
        }
    }
}

Kotlin 中的相同代码:

class MyAdapter(val itemClicks: (MyObject, Int) -> Unit): RecyclerView.Adapter<MyViewHolder>() {
    private var items: List<MyObject> = Collections.emptyList()

    fun updateData(items: List<MyObject>) {
        this.items = items
        notifyDataSetChanged() // TODO: use ListAdapter for diffing instead if you need animations
    }

    inner class MyViewHolder(val myView: View): RecyclerView.ViewHolder(myView) {
        private lateinit var myObject: MyObject

        init {
            // binds views
            myView.onClick {
                val adapterPosition = getAdapterPosition()
                if(adapterPosition >= 0) {
                    itemClicks.invoke(myObject, adapterPosition)
                }
            }
        }

        fun bind(myObject: MyObject) {
            this.myObject = myObject
            // bind data to views
        }
    }
}

不需要做的事情:

1.)您不需要手动拦截触摸事件

2.) 你不需要弄乱子附加状态更改侦听器

3.) 你不需要来自 RxJava 的 PublishSubject/PublishRelay

只需使用点击监听器。

于 2018-08-15T23:39:54.407 回答
10

我已经这样做了,它非常简单:

只需为Clicked RecyclerView 位置添加1 行

int position = getLayoutPosition()

ViewHolder类的完整代码:

private class ChildViewHolder extends RecyclerView.ViewHolder {
        public ImageView imageView;
        public TextView txtView;

        public ChildViewHolder(View itemView) {
            super(itemView);
            imageView= (ImageView)itemView.findViewById(R.id.imageView);
            txtView= (TextView) itemView.findViewById(R.id.txtView);
            itemView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    Log.i("RecyclerView Item Click Position", String.valueOf(getLayoutPosition()));
                }
            });
        }
    }

希望这会帮助你。

于 2016-02-03T13:44:31.867 回答
8

我使用此方法从 RecyclerView 启动 Intent:

@Override
 public void onBindViewHolder(ViewHolder viewHolder, int i) {

    final MyClass myClass = mList.get(i);
    viewHolder.txtViewTitle.setText(myclass.name);
   ...
    viewHolder.itemView.setOnClickListener(new View.OnClickListener() {
      @Override
       public void onClick(View v){
             Intent detailIntent = new Intent(mContext, type.class);                                                            
             detailIntent.putExtra("MyClass", myclass);
             mContext.startActivity(detailIntent);
       }
}
);
于 2015-06-06T17:54:10.353 回答
5

如果你想在item的子视图中添加onClick(),例如item中的一个按钮,我发现你可以在自己的RecyclerView.Adapter的onCreateViewHolder()中轻松做到,就像这样:

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

            Button btn = (Button) v.findViewById(R.id.btn);
            btn.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    //do it
                }
            });

            return new MyViewHolder(v);
        }

我不知道这是否是一个好方法,但它运作良好。如果有人有更好的想法,很高兴告诉我并纠正我的答案!:)

于 2015-11-30T12:46:20.607 回答
5

请参阅我的方法:

首先声明一个这样的接口:

/**
 * Interface used for delegating item click events in a {@link android.support.v7.widget.RecyclerView}
 * Created by Alex on 11/28/2015.
 */
  public interface OnRecyclerItemClickListener<T> {

     /**
      * Called when a click occurred inside a recyclerView item view
      * @param view that was clicked
      * @param position of the clicked view
      * @param item the concrete data that is displayed through the clicked view
      */
      void onItemClick(View view, int position, T item);
   }

然后创建适配器:

public class CustomRecyclerAdapter extends RecyclerView.Adapter {      

    private class InternalClickListener implements View.OnClickListener{

      @Override
      public void onClick(View v) {
        if(mRecyclerView != null && mItemClickListener != null){
            // find the position of the item that was clicked
            int position = mRecyclerView.getChildAdapterPosition(v);
            Data data = getItem(position);
            // notify the main listener
            mItemClickListener.onItemClick(v, position, data);
        }
    }
}

private final OnRecyclerItemClickListener mItemClickListener;
private RecyclerView mRecyclerView;    
private InternalClickListener mInternalClickListener;


/**
 *
 * @param itemClickListener used to trigger an item click event
 */
public PlayerListRecyclerAdapter(OnRecyclerItemClickListener itemClickListener){        
    mItemClickListener = itemClickListener;
    mInternalClickListener = new InternalClickListener();
}

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

    v.setOnClickListener(mInternalClickListener);

    ViewHolder viewHolder = new ViewHolder(v);
    return viewHolder;
}

@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
    // do your binding here
}

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

@Override
public void onAttachedToRecyclerView(RecyclerView recyclerView) {
    super.onAttachedToRecyclerView(recyclerView);

    mRecyclerView = recyclerView;
}

@Override
public void onDetachedFromRecyclerView(RecyclerView recyclerView) {
    super.onDetachedFromRecyclerView(recyclerView);

    mRecyclerView = null;
}

public Data getItem(int position){
    return mDataset.get(position);
}
}

现在让我们看看如何从片段中整合它:

public class TestFragment extends Fragment implements OnRecyclerItemClickListener<Data>{
   private RecyclerView mRecyclerView;

   @Override
   public void onItemClick(View view, int position, Data item) {
     // do something
   }

   @Override
   public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
      return inflater.inflate(R.layout.test_fragment, container, false);
   }

   @Override
   public void onViewCreated(View view, Bundle savedInstanceState) {
      mRecyclerView = view.findViewById(idOfTheRecycler);
      mRecyclerView .setAdapter(new CustomRecyclerAdapter(this));
   }
于 2015-11-28T13:09:28.237 回答
5

如果您有一个 POJO 列表并希望从适配器外部单击时检索一个 POJO,那么这是一种非常容易实现它的方法。

在您的适配器中,为单击事件创建一个侦听器和一个设置它的方法:

public class MyAdapter extends RecyclerView.Adapter<SitesListAdapter.ViewHolder> {
...
private List<MyPojo> mMyPojos;
private static OnItemClickListener mOnItemClickListener;

...
public interface OnItemClickListener {
    public void onItemClick(MyPojo pojo);
}

...
public void setOnItemClickListener(OnItemClickListener onItemClickListener){
    mOnItemClickListener = onItemClickListener;
}
...

}

在您的 ViewHolder 中,实现 onClickListener 并创建一个类成员来临时存储视图呈现的 POJO,这样(这是一个示例,创建一个 setter 会更好):

public static class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
    public MyPojo mCurrentPojo;
    ...
    public ViewHolder(View view) {
        super(v);
        ...
        view.setOnClickListener(this); //You could set this on part of the layout too
    }

    ...
    @Override
    public void onClick(View view) {
        if(mOnItemClickListener != null && mCurrentPojo != null){
            mOnItemClickListener.onItemClick(mCurrentPojo);
        }
    }

回到您的适配器,在绑定 ViewHolder 时设置当前 POJO(如果当前视图没有,则设置为 null):

@Override
public void onBindViewHolder(final ViewHolder holder, final int position) {
    final MyPojo currentPojo = mMyPojos.get(position); 
    holder.mCurrentPojo = currentPojo;
    ...

就是这样,现在您可以从片段/活动中像这样使用它:

    mMyAdapter.setOnItemClickListener(new mMyAdapter.OnItemClickListener() {
        @Override
        public void onItemClick(MyPojo pojo) {
            //Do whatever you want with your pojo here
        }
    });
于 2016-03-01T18:25:24.270 回答
4

是的你可以

public ViewHolder onCreateViewHolder(ViewGroup parent,int viewType) {

    //inflate the view 

    View view = LayoutInflator.from(parent.getContext()).inflate(R.layout.layoutID,null);

    ViewHolder holder = new ViewHolder(view);

    //here we can set onClicklistener
    view.setOnClickListener(new  View.OnClickListeener(){
        public void onClick(View v)
        {
            //action
        }
    });

return holder;
于 2016-07-28T06:38:42.793 回答
3

在这里您可以处理多个onclick,请参见下面的代码,它非常有效

    public class RVNewsAdapter extends RecyclerView.Adapter<RVNewsAdapter.FeedHolder> {

    private Context context;
    List<News> newsList;
    // Allows to remember the last item shown on screen
    private int lastPosition = -1;

    public RVNewsAdapter(List<News> newsList, Context context) {
        this.newsList = newsList;
        this.context = context;
    }

    public static class FeedHolder extends RecyclerView.ViewHolder implements OnClickListener {

        ImageView img_main;
        TextView tv_title;
        Button bt_facebook, bt_twitter, bt_share, bt_comment;


        public FeedHolder(View itemView) {
            super(itemView);

            img_main = (ImageView) itemView.findViewById(R.id.img_main);
            tv_title = (TextView) itemView.findViewById(R.id.tv_title);
            bt_facebook = (Button) itemView.findViewById(R.id.bt_facebook);
            bt_twitter = (Button) itemView.findViewById(R.id.bt_twitter);
            bt_share = (Button) itemView.findViewById(R.id.bt_share);
            bt_comment = (Button) itemView.findViewById(R.id.bt_comment);

            img_main.setOnClickListener(this);
            bt_facebook.setOnClickListener(this);
            bt_twitter.setOnClickListener(this);
            bt_comment.setOnClickListener(this);
            bt_share.setOnClickListener(this);

        }


        @Override
        public void onClick(View v) {

            if (v.getId() == bt_comment.getId()) {

                Toast.makeText(v.getContext(), "Comment  " , Toast.LENGTH_SHORT).show();

            } else if (v.getId() == bt_facebook.getId()) {

                Toast.makeText(v.getContext(), "Facebook  " , Toast.LENGTH_SHORT).show();

            } else if (v.getId() == bt_twitter.getId()) {

                Toast.makeText(v.getContext(), "Twitter  " , Toast.LENGTH_SHORT).show();

            } else if (v.getId() == bt_share.getId()) {

                Toast.makeText(v.getContext(), "share  " , Toast.LENGTH_SHORT).show();

            }
            else {
                Toast.makeText(v.getContext(), "ROW PRESSED = " + String.valueOf(getAdapterPosition()), Toast.LENGTH_SHORT).show();
            }
        }
    }

    @Override
    public void onAttachedToRecyclerView(RecyclerView recyclerView) {
        super.onAttachedToRecyclerView(recyclerView);
    }

    @Override
    public FeedHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.feed_row, parent, false);
        FeedHolder feedHolder = new FeedHolder(view);

        return feedHolder;
    }

    @Override
    public void onBindViewHolder(FeedHolder holder, int position) {

        holder.tv_title.setText(newsList.get(position).getTitle());


        // Here you apply the animation when the view is bound
        setAnimation(holder.img_main, position);
    }

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


    /**
     * Here is the key method to apply the animation
     */
    private void setAnimation(View viewToAnimate, int position) {
        // If the bound view wasn't previously displayed on screen, it's animated
        if (position > lastPosition) {
            Animation animation = AnimationUtils.loadAnimation(context, android.R.anim.slide_in_left);
            viewToAnimate.startAnimation(animation);
            lastPosition = position;
        }
    }


}
于 2016-08-05T13:07:03.300 回答
3

修改了我的评论...

public class MyViewHolder extends RecyclerView.ViewHolder {

        private Context mContext;

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

            mContext = itemView.getContext();

            itemView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {

                    int itemPosition = getLayoutPosition();
                    Toast.makeText(mContext, "" + itemPosition, Toast.LENGTH_SHORT).show();

                }
            });
        }
于 2016-08-26T14:27:38.857 回答
3

这对我有用:

@Override
public void onBindViewHolder(PlacesListViewAdapter.ViewHolder holder, int position) {
    ----
    ----
    ----
    // Set setOnClickListener(holder);
}


@Override
public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {

    ----
    ----
    ----

    @Override
    public void onClick(View view) {
        // Use to get the item clicked getAdapterPosition()
    }
}
于 2015-12-27T00:54:10.500 回答
2

检查这个我以正确的方式实现了所有东西的地方

RecyclerViewHolder 类

public class RecyclerViewHolder extends RecyclerView.ViewHolder  {

    //view holder is for girdview as we used in the listView
    public ImageView imageView,imageView2;
    public RecyclerViewHolder(View itemView) {
        super(itemView);
        this.imageView=(ImageView)itemView.findViewById(R.id.image);
    }

}

适配器

public class RecyclerView_Adapter extends RecyclerView.Adapter<RecyclerViewHolder> {

    //RecyclerView will extend to recayclerview Adapter
    private ArrayList<ModelClass> arrayList;
    private Context context;
    private static RecyclerViewClickListener itemListener;
    //constructor of the RecyclerView Adapter
    RecyclerView_Adapter(Context context,ArrayList<ModelClass> arrayList,RecyclerViewClickListener itemListener){
        this.context=context;
        this.arrayList=arrayList;
        this.itemListener=itemListener;
    }

    @Override
    public RecyclerViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        //this method will inflate the custom layout and return as viewHolder
        LayoutInflater layoutInflater=LayoutInflater.from(parent.getContext());
        ViewGroup mainGroup=(ViewGroup) layoutInflater.inflate(R.layout.single_item,parent,false);
        RecyclerViewHolder listHolder=new RecyclerViewHolder(mainGroup);

        return listHolder;
    }

    @Override
    public void onBindViewHolder(RecyclerViewHolder holder, final int position) {

        final ModelClass modelClass=arrayList.get(position);
        //holder
        RecyclerViewHolder mainHolder=(RecyclerViewHolder)holder;
        //convert the drawable image into bitmap
        Bitmap image= BitmapFactory.decodeResource(context.getResources(),modelClass.getImage());
        //set the image into imageView
        mainHolder.imageView.setImageBitmap(image);
        //to handle on click event when clicked on the recyclerview item and
        // get it through the RecyclerViewHolder class we have defined the views there
        mainHolder.itemView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //get the position of the image which is clicked
             itemListener.recyclerViewListClicked(v,position);
            }
        });

    }

    @Override
    public int getItemCount() {
        return (null!=arrayList?arrayList.size():0);
    }
}

界面

public interface RecyclerViewClickListener {

    //this is method to handle the event when clicked on the image in Recyclerview
    public void recyclerViewListClicked(View v,int position);
}

//and to call this method in activity
RecyclerView_Adapter adapter=new RecyclerView_Adapter(Wallpaper.this,arrayList,this);
        recyclerView.setAdapter(adapter);
        adapter.notifyDataSetChanged();


    @Override
    public void  recyclerViewListClicked(View v,int position){

        imageView.setImageResource(wallpaperImages[position]);

    }
于 2017-02-04T13:48:26.717 回答
2

mainViewrowLayout(cell)您访问RecyclerView并在您的代码中OnBindViewHolder编写以下代码:

    @Override
    public void onBindViewHolder(MyViewHolder holder, final int position) {
        Movie movie = moviesList.get(position);
        holder.mainView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                System.out.println("pos " + position);
            }
        });
    }
于 2017-07-18T14:39:19.573 回答
2

它对我有用。希望它会有所帮助。最简单的方法。

内部视图架

class GeneralViewHolder extends RecyclerView.ViewHolder {
    View cachedView = null;

    public GeneralViewHolder(View itemView) {
        super(itemView);
        cachedView = itemView;
    }

OnBindViewHolder() 内部

@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, final int position) {
            final GeneralViewHolder generalViewHolder = (GeneralViewHolder) holder;
            generalViewHolder.cachedView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    Toast.makeText(context, "item Clicked at "+position, Toast.LENGTH_SHORT).show();
                }
            });

让我知道,您对此解决方案有任何疑问吗?

于 2017-09-06T10:18:32.913 回答
1

使用PlaceHolderView

@Layout(R.layout.item_view_1)
public class View1{

    @View(R.id.txt)
    public TextView txt;

    @Resolve
    public void onResolved() {
        txt.setText(String.valueOf(System.currentTimeMillis() / 1000));
    }

    @Click(R.id.btn)
    public void onClick(){
        txt.setText(String.valueOf(System.currentTimeMillis() / 1000));
    }
}
于 2016-08-19T08:43:31.057 回答
1
 main_recyclerview.addOnItemTouchListener(new RecyclerView.OnItemTouchListener() {
        @Override
        public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e)
        {
            int position=rv.getChildAdapterPosition(rv.findChildViewUnder(e.getX(),e.getY()));

            switch (position)
            {
                case 0:
                {
                    wifi(position);
                    adapter2.notifyDataSetChanged();
                }
                break;

                case 1:
                {
                    sound(position);
                    adapter2.notifyDataSetChanged();
                }
                break;

                case 2:
                {
                    bluetooth(position);
                    adapter2.notifyDataSetChanged();
                }
                break;


            }
            return true;
        }

        @Override
        public void onTouchEvent(RecyclerView rv, MotionEvent e)
        {

        }

        @Override
        public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {

        }
    });
于 2017-10-07T10:17:54.733 回答
1

而不是在视图持有者内实现接口 View.OnClickListener 或在您的活动中创建接口和实现接口。我使用此代码来简单地实现 OnClickListener 。

public static class SimpleStringRecyclerViewAdapter
            extends RecyclerView.Adapter<SimpleStringRecyclerViewAdapter.ViewHolder> {

        // Your initializations goes here...
        private List<String> mValues;

        public static class ViewHolder extends RecyclerView.ViewHolder {

            //create a variable mView
            public final View mView;

            /*All your row widgets goes here
            public final ImageView mImageView;
            public final TextView mTextView;*/

            public ViewHolder(View view) {
                super(view);
                //Initialize it here
                mView = view;

                /* your row widgets initializations goes here
                mImageView = (ImageView) view.findViewById(R.id.avatar);
                mTextView = (TextView) view.findViewById(android.R.id.text1);*/
            }
        }

        public String getValueAt(int position) {
            return mValues.get(position);
        }

        public SimpleStringRecyclerViewAdapter(Context context, List<String> items) {

            mBackground = mTypedValue.resourceId;
            mValues = items;
        }

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

        @Override
        public void onBindViewHolder(final ViewHolder holder, int position) {
            holder.mBoundString = mValues.get(position);
            holder.mTextView.setText(mValues.get(position));

            //Here it is simply write onItemClick listener here
            holder.mView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    Context context = v.getContext();
                    Intent intent = new Intent(context, ExampleActivity.class);

                    context.startActivity(intent);
                }
            });
        }

        @Override
        public int getItemCount() {
            return mValues.size();
        }
    }
于 2015-10-07T06:38:43.090 回答
0

我写了一个库来处理 android recycler view item click 事件。您可以在https://github.com/ChathuraHettiarachchi/RecycleClick中找到整个教程

RecycleClick.addTo(YOUR_RECYCLEVIEW).setOnItemClickListener(new RecycleClick.OnItemClickListener() {
            @Override
            public void onItemClicked(RecyclerView recyclerView, int position, View v) {
                // YOUR CODE
            }
        });

或处理项目长按,您可以使用

RecycleClick.addTo(YOUR_RECYCLEVIEW).setOnItemLongClickListener(new RecycleClick.OnItemLongClickListener() {
            @Override
            public boolean onItemLongClicked(RecyclerView recyclerView, int position, View v) {
                // YOUR CODE
                return true;
            }
        });
于 2017-02-02T11:54:47.477 回答
0

recyclerview动画没测试过,其他都正常。我认为它已被优化到最大。接口还有其他用途,可以暂时忽略。

public abstract class BaseAdapterRV<VH extends BaseViewHolder> extends RecyclerView.Adapter<VH> implements AdapterInterface {
    public final String TAG = getClass().getSimpleName();

    protected final Activity mActivity;
    protected final LayoutInflater mInflater;
    protected ItemClickInterface<?, Integer> mListener;

    public BaseAdapterRV(Activity activity) {
        mActivity = activity;
        mInflater = LayoutInflater.from(mActivity);
    }

    @Override
    public final VH onCreateViewHolder(ViewGroup parent, int viewType) {
        return onCreateViewHolder(parent, viewType, mInflater);
    }

    @Override
    public final void onBindViewHolder(VH holder, int position) {
        holder.itemView.setTag(R.id.tag_view_click, position);
        //创建点击事件
        holder.itemView.setOnClickListener(mListener);
        holder.itemView.setOnLongClickListener(mListener);
        onBindVH(holder, position);
    }


    ///////////////////////////////////////////////////////////////////////////
    // 以下是增加的方法
    ///////////////////////////////////////////////////////////////////////////

    /**
     * 注意!涉及到notifyItemInserted刷新时立即获取position可能会不正确
     * 里面也有onItemLongClick
     */
    public void setOnItemClickListener(ItemClickInterface<?, Integer> listener) {
        mListener = listener;
        notifyDataSetChanged();
    }

    @NonNull
    protected abstract VH onCreateViewHolder(ViewGroup parent, int viewType, LayoutInflater inflater);

    protected abstract void onBindVH(VH holder, int position);

}

这是接口

/**
 * OnItemClickListener的接口
 * 见子类实现{@link OnItemClickListener}{@link OnItemItemClickListener}
 */
public interface ItemClickInterface<DATA1, DATA2> extends View.OnClickListener, View.OnLongClickListener {

    void onItemClick(DATA1 data1, DATA2 data2);

    boolean onItemLongClick(DATA1 data1, DATA2 data2);
}

这是一个抽象类

public abstract class OnItemClickListener<DATA> implements ItemClickInterface<View, DATA> {
    @Override
    public void onClick(View v) {
        onItemClick(v, (DATA) v.getTag(R.id.tag_view_click));
    }

    @Override
    public boolean onLongClick(View v) {
        return onItemLongClick(v, (DATA) v.getTag(R.id.tag_view_click));
    }

    @Override
    public boolean onItemLongClick(View view, DATA data) {
        return false;
    }
}

你只需要它

    mAdapter.setOnItemClickListener(new OnItemClickListener<Integer>() {
        @Override
        public void onItemClick(View view, Integer integer) {

        }

        @Override
        public boolean onItemLongClick(View view, Integer integer) {
            return true;
        }
    });
于 2017-11-16T03:07:20.720 回答
0

我发现了使用 androidx 生命周期可变实时数据的最短方法之一

适配器:

private val onItemClickListener = MutableLiveData<YourAdapterItem>()


override fun onBindViewHolder(holder: GifsViewHolder, position: Int) {
    holder.itemView.setOnClickListener { onItemClickListener.value = gifs[position] }
}
fun getOnItemClickListener(): MutableLiveData<Gif> {
    return onItemClickListener
}

MainActivity 中的任何位置

    yourFancyAdapter.getOnItemClickListener().observe(this, Observer {
        println(it)
    })
于 2020-09-11T14:48:24.360 回答
-5

最简单的方法如下:

在 Adapter 类的开头声明全局变量:

// Store out here so we can resuse
private View yourItemView;

然后在onBindViewHolder方法中设置 OnClickListener:

@Override
public void onBindViewHolder(BusinessAdapter.ViewHolder holder, int position) {

    // Set up the on click listener
    yourItemView.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View v) {
            Toast.makeText(mContext,Integer.toString(position),Toast.LENGTH_SHORT).show();
        }
    });

}

所有其他答案都不正确。

于 2017-07-23T07:15:07.453 回答