刷卡和的OnClick事件RecyclerView [英] Swipe and OnClick events in RecyclerView
问题描述
我想实现刷卡驳回了RecyclerView动作,但是当我在一个ViewHolder设置OnClickListener任何查看它覆盖在该视图中的所有OnTouch事件。
我可以放弃OnClickListener和处理所有的点击在TouchListener,但如果我在RecycleView比子视图多个按钮将是一个很大的code,这看起来并不像一个正确的方式。
在我RecyleView我设置刷卡解雇听众(与此类似):
setOnTouchListener(touchListener);
setOnScrollListener(touchListener.makeScrollListener());
它的工作原理在ListView,但在RecycleView的OnClickListener块OnTouchListner事件。
有关ViewHolder视图布局的实例。
< RelativeLayout的的xmlns:机器人=http://schemas.android.com/apk/res/android
的xmlns:程序=http://schemas.android.com/apk/res-auto
机器人:ID =@ + ID / card_title
机器人:layout_width =match_parent
机器人:layout_height =WRAP_CONTENT
机器人:=了minHeight72dp
机器人:descendantFocusability =blocksDescendants>
< ImageView的
机器人:ID =@ + ID / keep_icon
机器人:layout_width =48dp
机器人:layout_height =48dp
机器人:layout_centerInParent =真
机器人:SRC =@可绘制/ ic_received/>
充气的RecyclerView.Adapter:
@覆盖
公共ViewHolder onCreateViewHolder(ViewGroup中的ViewGroup,int i)以{
视图V = mInflater.inflate(R.layout.push_card_view_compat,ViewGroup中,假);
返回新ViewHolder(V,onClickListener,onKeepListener);
}
在ViewHolder:
公共ViewHolder(最终查看ItemView控件,
最后OnViewHolderClickListener onClickListener,
最后OnKeepListener onKeepListener){
超(ItemView控件);
keepButton =(ImageView的)itemView.findViewById(R.id.keep_icon);
itemView.setOnClickListener(新View.OnClickListener(){
@覆盖
公共无效的onClick(视图v){
onItemClickListener.onClick(为getPosition(),ItemView控件);
}
});
keepButton.setOnClickListener(新View.OnClickListener(){
@覆盖
公共无效的onClick(视图v){
onKeepListener.onClick(为getPosition(),ItemView控件);
}
});
}
我实现了通过指定 OnClickListener
在 ViewHolder 按钮code>,并创造了触摸事件的接口。
示例项目是在GitHub上:<一href="https://github.com/brnunes/SwipeableRecyclerView">https://github.com/brnunes/SwipeableRecyclerView.
在我的情况下,每个项目是 CardView
有两个按钮,我要检测的触摸事件的 CardView
和按钮
秒。该 CardView
的布局是这样的:
&LT; XML版本=1.0编码=UTF-8&GT?;
&LT; android.support.v7.widget.CardView的xmlns:机器人=http://schemas.android.com/apk/res/android
的xmlns:card_view =http://schemas.android.com/apk/res-auto
机器人:layout_width =match_parent
机器人:layout_height =match_parent
机器人:layout_margin =5DP
机器人:可点击=真
机器人:前景=机器人:ATTR / selectableItemBackground
机器人:方向=垂直
card_view:cardCornerRadius =5DP&GT;
&LT; RelativeLayout的
机器人:layout_width =match_parent
机器人:layout_height =match_parent&GT;
&LT;的TextView
机器人:ID =@ + ID / card_view_title
机器人:layout_width =match_parent
机器人:layout_height =50dp
机器人:layout_alignParentTop =真
机器人:layout_centerHorizontal =真
机器人:重力=中心
机器人:文字颜色=@机器人:彩色/黑白
机器人:TEXTSIZE =24sp/&GT;
&LT;的LinearLayout
机器人:layout_width =match_parent
机器人:layout_height =WRAP_CONTENT
机器人:layout_alignParentBottom =真
机器人:layout_below =@ ID / card_view_title
机器人:layout_centerHorizontal =真
机器人:重力=中心&GT;
&LT;按钮
机器人:ID =@ + ID / card_view_button1
机器人:layout_width =WRAP_CONTENT
机器人:layout_height =WRAP_CONTENT
机器人:文本=Button1的/&GT;
&LT;按钮
机器人:ID =@ + ID / card_view_button2
机器人:layout_width =WRAP_CONTENT
机器人:layout_height =WRAP_CONTENT
机器人:文本=Button2的/&GT;
&LT; / LinearLayout中&GT;
&LT; / RelativeLayout的&GT;
&LT; /android.support.v7.widget.CardView>
然后在活动
,我宣布接收触摸事件的接口:
公共接口OnItemTouchListener {
公共无效onCardViewTap(查看视图,INT位置);
公共无效onButton1Click(查看视图,INT位置);
公共无效onButton2Click(查看视图,INT位置);
}
而在 ViewHolder
我给 OnClickListeners
来,我要听的对象,并调用我的自定义听众:
公共类CardViewAdapter扩展RecyclerView.Adapter&LT; CardViewAdapter.ViewHolder&GT; {
私人列表&LT;字符串&GT;牌;
私人OnItemTouchListener onItemTouchListener;
公共CardViewAdapter(名单&LT;字符串&GT;卡,OnItemTouchListener onItemTouchListener){
this.cards =卡;
this.onItemTouchListener = onItemTouchListener;
}
@覆盖
公共ViewHolder onCreateViewHolder(ViewGroup中的ViewGroup,int i)以{
视图V = LayoutInflater.from(viewGroup.getContext())膨胀(R.layout.card_view_layout,ViewGroup中,假的)。
返回新ViewHolder(V);
}
@覆盖
公共无效onBindViewHolder(ViewHolder viewHolder,int i)以{
viewHolder.title.setText(cards.get(ⅰ));
}
@覆盖
公众诠释getItemCount(){
返回卡== NULL? 0:cards.size();
}
公共类ViewHolder扩展RecyclerView.ViewHolder {
私人TextView的称号;
私人按钮按钮1;
私人按钮按钮2;
公共ViewHolder(查看ItemView控件){
超(ItemView控件);
标题=(TextView中)itemView.findViewById(R.id.card_view_title);
按钮1 =(按钮)itemView.findViewById(R.id.card_view_button1);
按钮2 =(按钮)itemView.findViewById(R.id.card_view_button2);
button1.setOnClickListener(新View.OnClickListener(){
@覆盖
公共无效的onClick(视图v){
onItemTouchListener.onButton1Click(ⅴ为getPosition());
}
});
button2.setOnClickListener(新View.OnClickListener(){
@覆盖
公共无效的onClick(视图v){
onItemTouchListener.onButton2Click(ⅴ为getPosition());
}
});
itemView.setOnClickListener(新View.OnClickListener(){
@覆盖
公共无效的onClick(视图v){
onItemTouchListener.onCardViewTap(ⅴ为getPosition());
}
});
}
}
}
最后,实例化自定义的 OnItemTouchListener
,并把它传递给 CardViewAdapter
构造器:
@覆盖
保护无效的onCreate(包savedInstanceState){
super.onCreate(savedInstanceState);
的setContentView(R.layout.activity_main);
mItems =新的ArrayList&LT;&GT;(30);
的for(int i = 0;我小于30;我++){
mItems.add(的String.Format(卡号%2D,I));
}
OnItemTouchListener itemTouchListener =新OnItemTouchListener(){
@覆盖
公共无效onCardViewTap(查看视图,INT位置){
Toast.makeText(MainActivity.this,抽头+ mItems.get(位置),Toast.LENGTH_SHORT).show();
}
@覆盖
公共无效onButton1Click(查看视图,INT位置){
Toast.makeText(MainActivity.this,已点击Button1的中的+ mItems.get(位置),Toast.LENGTH_SHORT).show();
}
@覆盖
公共无效onButton2Click(查看视图,INT位置){
Toast.makeText(MainActivity.this,已点击将Button2的+ mItems.get(位置),Toast.LENGTH_SHORT).show();
}
};
mAdapter =新CardViewAdapter(mItems,itemTouchListener);
mRecyclerView =(RecyclerView)findViewById(R.id.recycler_view);
mRecyclerView.setLayoutManager(新LinearLayoutManager(本));
mRecyclerView.setAdapter(mAdapter);
// ...分配刷卡监听器
}
I'm trying to implement a swipe to dismiss action in a RecyclerView but when I set an OnClickListener on any View in a ViewHolder it overrides all OnTouch events on that view.
I can abandon OnClickListener and handle all clicks in the TouchListener but if I have multiple buttons in a child view of the RecycleView than that will be a lot of code and this doesn't look like a right way.
In my RecyleView I'm setting Swipe to dismiss listeners (similar to this):
setOnTouchListener(touchListener);
setOnScrollListener(touchListener.makeScrollListener());
It works in the ListView, but in the RecycleView the OnClickListener blocks OnTouchListner events.
Example of the layout for ViewHolder view.
<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" />
Inflating in the 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);
}
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);
}
});
}
I achieved that by assigning OnClickListener
for the buttons in the ViewHolder
, and creating an interface for the touch events.
The sample project is on GitHub: https://github.com/brnunes/SwipeableRecyclerView.
In my case each item is a CardView
with two buttons, and I want to detect the touch events in the CardView
and the Button
s. The CardView
layout looks like this:
<?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>
Then in the Activity
, I declared an interface to receive the touch events:
public interface OnItemTouchListener {
public void onCardViewTap(View view, int position);
public void onButton1Click(View view, int position);
public void onButton2Click(View view, int position);
}
And in the ViewHolder
I assign OnClickListeners
to the objects that I want to listen to, and call my custom listener:
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());
}
});
}
}
}
Finally, instantiate the custom OnItemTouchListener
and pass it to the CardViewAdapter
constructor:
@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
}
这篇关于刷卡和的OnClick事件RecyclerView的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!