Événements Swipe et OnClick dans RecyclerView
j'essaie d'implémenter un swipe pour rejeter l'action dans un RecyclerView mais quand je mets un OnClickListener sur n'importe quelle vue dans un ViewHolder il l'emporte sur tous les événements OnTouch sur cette vue.
je peux abandonner OnClickListener et gérer tous les clics dans le TouchListener mais si j'ai plusieurs boutons dans une vue enfant du RecycleView que ce sera beaucoup de code et cela ne ressemble pas à une bonne façon.
dans ma vision RecyleView, je mets Swipe pour écarter les auditeurs ( semblable à ceci):
setOnTouchListener(touchListener);
setOnScrollListener(touchListener.makeScrollListener());
il fonctionne dans la ListView, mais dans la RecycleView L'OnClickListener bloque sur les événements de listner.
exemple de la mise en page pour la vue 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" />
gonflage dans le RecyclerView.Adaptateur:
@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);
}
The 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);
}
});
}
1 réponses
j'y suis arrivé en assignant OnClickListener
pour les boutons dans le ViewHolder
, et la création d'une interface pour les événements tactiles.
Le projet est sur GitHub: https://github.com/brnunes/SwipeableRecyclerView.
Dans mon cas, chaque élément est un CardView
avec deux boutons, et je veux détecter les événements de toucher dans le CardView
et Button
s. CardView
mise en page ressemble à ceci:
<?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>
Puis dans le Activity
j'ai déclaré un interface pour recevoir les événements tactiles:
public interface OnItemTouchListener {
public void onCardViewTap(View view, int position);
public void onButton1Click(View view, int position);
public void onButton2Click(View view, int position);
}
Et ViewHolder
- je attribuer OnClickListeners
pour les objets que je veux écouter, et faire appel à mon écouteur personnalisé:
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());
}
});
}
}
}
enfin, instanciez la coutume OnItemTouchListener
et passer à la CardViewAdapter
constructeur:
@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
}