我试图在RecyclerView中实现一个swipe来解除操作,但当我在ViewHolder中的任何视图上设置OnClickListener时,它将覆盖该视图上的所有OnTouch事件。
我可以放弃OnClickListener而在TouchListener中处理所有单击,但如果在RecycleView的子视图中有多个按钮,那么将会有大量代码,这看起来不是一个正确的方法。
在我的RecyleView中,我将Swipe设置为Discount侦听器(与此类似):
setOnTouchListener(touchListener);
setOnScrollListener(touchListener.makeScrollListener());
它在ListView中工作,但在RecycleView中,OnClickListener阻止OnTouchListner事件。
ViewWholder视图的布局示例。
<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);
}
观众:
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);
}
});
}
我通过为viewholder
中的按钮分配onclicklistener
并为touch事件创建一个接口来实现这一点。
示例项目位于GitHub:https://github.com/brnunes/SwipeableRecyclerView上。
在我的示例中,每个项都是一个带有两个按钮的CardView
,我希望检测CardView
和按钮
中的触摸事件。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
}
我想实现像Google Play App一样的平滑滚动行为。我尝试过这里提到的解决方案: 解决方案1 解决方案2 解决方案3 但所有上述解决方案都没有像在Google Play应用程序中那样给出预期的结果。以下是xml代码: 如何实现平滑滚动? 编辑:以下是recyclerview适配器 }
问题是将作为参数,根据文档,该参数是“RecyclerView正在绘制其子级的画布”。有没有办法从中获取画布?如果执行,则会执行代码,但在ViewWholder后面没有绘制任何内容,因为它显然不是recyclerview使用的画布...也许有办法设置一个canvas供recyclerview使用吗? 谢谢你的正手点子。
我查看了一些教程,了解片段之间的动画事务。我用这种方法制作动画,效果很好: 但是我想反转这个动画:旧片段滑出到左边,新片段滑入到右边,但是文件的值似乎对我的作用域没有用处。 我怎么能做到呢?
在适配器中 我试过了所有的方法,但是很难从RecolyerView中滑动项目,并且当snackbar的undo被按下时,我希望该项目重新出现。我希望从RecolyerView中滑动项目,并且当项目被滑动时,底部的项目应该向上移动。
我正在尝试为我的RecolyerView添加滑动功能。我正在跟随这个链接添加刷卡。https://github.com/nikhilpanju/recyclerviewenhanced/blob/master/recyclerviewenhanced/src/main/java/com/nikhilpanju/recyclerviewenhanced/recyclertouchlistener.j