在RecyclerView中滑动和OnClick事件

我试图在RecyclerView中实施滑动来消除动作,但是当我在ViewHolder中的任何View上设置OnClickListener时,它将覆盖该视图上的所有OnTouch事件。

我可以放弃OnClickListener并处理TouchListener中的所有点击,但是如果我在RecycleView的子视图中有多个button,那么将会有很多代码,这看起来不是一个正确的方法。

在我的RecyleView中,我正在设置Swipe来closures监听器( 与此类似 ):

setOnTouchListener(touchListener); setOnScrollListener(touchListener.makeScrollListener()); 

它在ListView中工作,但在RecycleView中,OnClickListener阻止了OnTouchListner事件。

ViewHolder视图的布局示例。

 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:id="@+id/card_title" android:layout_width="match_parent" android:layout_height="wrap_content" android:minHeight="72dp" android:descendantFocusability="blocksDescendants"> <ImageView android:id="@+id/keep_icon" android:layout_width="48dp" android:layout_height="48dp" android:layout_centerInParent="true" android:src="@drawable/ic_received" /> 

在RecyclerView.Adapter中充气:

 @Override public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) { View v = mInflater.inflate(R.layout.push_card_view_compat, viewGroup, false); return new ViewHolder(v, onClickListener, onKeepListener); } 

ViewHolder:

 public ViewHolder(final View itemView, final OnViewHolderClickListener onClickListener, final OnKeepListener onKeepListener) { super(itemView); keepButton = (ImageView) itemView.findViewById(R.id.keep_icon); itemView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { onItemClickListener.onClick(getPosition(), itemView); } }); keepButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { onKeepListener.onClick(getPosition(), itemView); } }); } 

Solutions Collecting From Web of "在RecyclerView中滑动和OnClick事件"

我通过为OnClickListener中的button分配OnClickListener并为触摸事件创build一个接口来实现这一点。

示例项目位于GitHub上: https : //github.com/brnunes/SwipeableRecyclerView 。

在我的情况下,每个项目是一个有两个button的CardView ,我想检测CardViewButton的触摸事件。 CardView布局看起来像这样:

 <?xml version="1.0" encoding="utf-8"?> <android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android" xmlns:card_view="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_margin="5dp" android:clickable="true" android:foreground="?android:attr/selectableItemBackground" android:orientation="vertical" card_view:cardCornerRadius="5dp"> <RelativeLayout android:layout_width="match_parent" android:layout_height="match_parent"> <TextView android:id="@+id/card_view_title" android:layout_width="match_parent" android:layout_height="50dp" android:layout_alignParentTop="true" android:layout_centerHorizontal="true" android:gravity="center" android:textColor="@android:color/black" android:textSize="24sp" /> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:layout_below="@id/card_view_title" android:layout_centerHorizontal="true" android:gravity="center"> <Button android:id="@+id/card_view_button1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Button1" /> <Button android:id="@+id/card_view_button2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Button2" /> </LinearLayout> </RelativeLayout> </android.support.v7.widget.CardView> 

然后在Activity ,我声明了一个接口来接收触摸事件:

 public interface OnItemTouchListener { public void onCardViewTap(View view, int position); public void onButton1Click(View view, int position); public void onButton2Click(View view, int position); } 

ViewHolder我将OnClickListeners分配给我想要侦听的对象,并调用我的自定义侦听器:

 public class CardViewAdapter extends RecyclerView.Adapter<CardViewAdapter.ViewHolder> { private List<String> cards; private OnItemTouchListener onItemTouchListener; public CardViewAdapter(List<String> cards, OnItemTouchListener onItemTouchListener) { this.cards = cards; this.onItemTouchListener = onItemTouchListener; } @Override public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) { View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.card_view_layout, viewGroup, false); return new ViewHolder(v); } @Override public void onBindViewHolder(ViewHolder viewHolder, int i) { viewHolder.title.setText(cards.get(i)); } @Override public int getItemCount() { return cards == null ? 0 : cards.size(); } public class ViewHolder extends RecyclerView.ViewHolder { private TextView title; private Button button1; private Button button2; public ViewHolder(View itemView) { super(itemView); title = (TextView) itemView.findViewById(R.id.card_view_title); button1 = (Button) itemView.findViewById(R.id.card_view_button1); button2 = (Button) itemView.findViewById(R.id.card_view_button2); button1.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { onItemTouchListener.onButton1Click(v, getPosition()); } }); button2.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { onItemTouchListener.onButton2Click(v, getPosition()); } }); itemView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { onItemTouchListener.onCardViewTap(v, getPosition()); } }); } } } 

最后,实例化自定义OnItemTouchListener并将其传递给CardViewAdapter构造函数:

 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mItems = new ArrayList<>(30); for (int i = 0; i < 30; i++) { mItems.add(String.format("Card number %2d", i)); } OnItemTouchListener itemTouchListener = new OnItemTouchListener() { @Override public void onCardViewTap(View view, int position) { Toast.makeText(MainActivity.this, "Tapped " + mItems.get(position), Toast.LENGTH_SHORT).show(); } @Override public void onButton1Click(View view, int position) { Toast.makeText(MainActivity.this, "Clicked Button1 in " + mItems.get(position), Toast.LENGTH_SHORT).show(); } @Override public void onButton2Click(View view, int position) { Toast.makeText(MainActivity.this, "Clicked Button2 in " + mItems.get(position), Toast.LENGTH_SHORT).show(); } }; mAdapter = new CardViewAdapter(mItems, itemTouchListener); mRecyclerView = (RecyclerView) findViewById(R.id.recycler_view); mRecyclerView.setLayoutManager(new LinearLayoutManager(this)); mRecyclerView.setAdapter(mAdapter); // ... Assign the swipe listener }