Салфетки и события onclick в RecyclerView
Я пытаюсь реализовать свайп, чтобы отклонить действие в RecyclerView, но когда я устанавливаю OnClickListener на любом представлении в ViewHolder, он переопределяет все события OnTouch на этом представлении.
Я могу отказаться от OnClickListener и обрабатывать все клики в TouchListener, но если у меня есть несколько кнопок в дочернем представлении RecycleView, то это будет много кода, и это не похоже на правильный путь.
В моем RecyleView я устанавливаю Swipe, чтобы уволить слушателей (аналогично это):
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.Адаптер:
@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);
}
Владелец Вида:
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);
}
});
}
1 ответ:
Я добился этого, назначив
OnClickListener
для кнопок вViewHolder
и создав интерфейс для сенсорных событий.Образец проекта на GitHub: https://github.com/brnunes/SwipeableRecyclerView.
В моем случае каждый элемент является
CardView
с двумя кнопками, и я хочу обнаружить события касания вCardView
иButton
s. расположение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 }