我正在探索RecyclerView
,我很惊讶地看到RecyclerView
它没有onItemClickListener()
.因为RecyclerView
延伸
android.view.ViewGroup
并ListView
扩展
android.widget.AbsListView
.不过,我解决我的问题写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) { } }
但我仍然想知道为什么谷歌被删除了onItemClickListener()
?
是否有性能问题或其他问题?
据我所知,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(); } }
> RecyclerView与Listview有何不同?
一个区别是有一个LayoutManager
使用RecyclerView的课程,您可以通过它管理您的喜欢RecyclerView
-
水平或垂直滚动
LinearLayoutManager
GridLayout by
GridLayoutManager
交错的GridLayout by
StaggeredGridLayoutManager
对于RecyclerView的水平滚动 -
LinearLayoutManager llm = new LinearLayoutManager(context); llm.setOrientation(LinearLayoutManager.HORIZONTAL); recyclerView.setLayoutManager(llm);
伙计们在您的主要活动中使用此代码.非常有效的方法
RecyclerView recyclerView = (RecyclerView) findViewById(R.id.users_list); UsersAdapter adapter = new UsersAdapter(users, this); recyclerView.setAdapter(adapter); adapter.setOnCardClickListner(this);
这是你的Adapter类.
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); }
跟进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);
修改原始tl; dr为:
public Observable<String> getPositionClicks(){ return onClickSubject; }
PublishSubject#asObservable()
去掉了.只需返回PublishSubject
哪个是Observable
.
如何把它们放在一起的例子......
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); } }
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 } } }
如果您有一个POJO列表并希望从适配器外部单击检索一个POJO,则可以非常轻松地实现它.
在适配器中,为click事件创建一个侦听器,并设置一个方法来设置它:
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 } });
我这样做了,非常简单:
只需为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())); } }); } }
希望这会帮助你.
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(); } }
原帖:
自推出以来ListView
,onItemClickListener
一直存在问题.当你有任何内部元素的点击监听器时,不会触发回调但是没有通知或记录良好(如果有的话),所以存在很多混淆和SO问题.
鉴于RecyclerView
它更进一步,并没有行/列的概念,而是任意布局的子项数量,他们已经将onClick委托给它们中的每一个,或者程序员实现.
可以认为Recyclerview
不是ListView
1: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
迄今为止的内部实现和改进非常接近.谷歌最终承认这一点很好.
阅读@ 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); } } }
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); } }) );
我使用这个方法从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); } } );
我喜欢这种方式而且我正在使用它
内
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)); } }
我以前读过有更好的方法,但我喜欢这种方式很容易而且不复杂.
另一种解决方案是由Android GDE的Hugo Visser 提出的解决方案.他为您提供了免费许可课程,您只需输入代码并使用它即可.
用法:
recyclerView.onItemClick { recyclerView, position, v -> // do it }
(它还支持长项目点击)
实施(评论由我添加):
typealias OnRecyclerViewItemClickListener = (recyclerView: RecyclerView, position: Int, v: View) -> Unit typealias OnRecyclerViewItemLongClickListener = (recyclerView: RecyclerView, position: Int, v: View) -> Boolean class ItemClickSupport(private val recyclerView: RecyclerView) { private var onItemClickListener: OnRecyclerViewItemClickListener? = null private var onItemLongClickListener: OnRecyclerViewItemLongClickListener? = null private val attachListener: RecyclerView.OnChildAttachStateChangeListener by lazy { 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) } }
还创建一个文件ItemClickSupportViewHolder
并将其放入其中:
class MyViewHolder(view): RecyclerView.ViewHolder(view), ItemClickSupportViewHolder { override val isClickable: Boolean get() = false override val isLongClickable: Boolean get() = false }
这个类通过附加ViewHolder
到values/ids.xml
.每次儿童被附加或分离时,都会通知该听众RecyclerView.OnChildAttachStateChangeListener
.代码使用此选项将点击/长按侦听器附加到视图.这听众问RecyclerView
了RecyclerView
其中包含的位置.
如果您需要更多,您还可以调整代码以便为您提供支持.
请记住,通过在列表的每个视图上设置一个点击监听器,就像其他建议的答案一样,在您的适配器中处理它完全没问题.这不是最有效的事情(每次重复使用视图时都会创建一个新的侦听器),但它可以工作,在大多数情况下它不是问题.
关于为什么 RecyclerView
没有RecyclerView.ViewHolder
.
这onItemClickListener
是一个工具箱,RecyclerView
与之相反,它具有较少的功能构建和更大的灵活性.这ListView
不是从ListView中删除的唯一功能.但它有很多听众和方法可以根据自己的喜好扩展它,它在右手中更强大;).
在我看来,删除的最复杂的功能onItemClickListener
是快速滚动.大多数其他功能可以轻松重新实现.
感谢@marmor,我更新了我的答案.
我认为在ViewHolder类构造函数中处理onClick()并通过OnItemClickListener接口将其传递给父类是一个很好的解决方案.
MyAdapter.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 } } }