刷卡和的OnClick事件RecyclerView [英] Swipe and OnClick events in RecyclerView

查看:257
本文介绍了刷卡和的OnClick事件RecyclerView的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想实现刷卡驳回了RecyclerView动作,但是当我在一个ViewHolder设置OnClickListener任何查看它覆盖在该视图中的所有OnTouch事件。

我可以放弃OnClickListener和处理所有的点击在TouchListener,但如果我在RecycleView比子视图多个按钮将是一个很大的code,这看起来并不像一个正确的方式。

在我RecyleView我设置刷卡解雇听众(与此类似):

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

它的工作原理在ListView,但在RecycleView的OnClickListener块OnTouchListner事件。

有关ViewHolder视图布局的实例。

 < RelativeLayout的的xmlns:机器人=htt​​p://schemas.android.com/apk/res/android
的xmlns:程序=htt​​p://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 ,并创造了触摸事件的接口。

示例项目是在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:机器人=htt​​p://schemas.android.com/apk/res/android
    的xmlns:card_view =htt​​p://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_centerHorizo​​ntal =真
            机器人:重力=中心
            机器人:文字颜色=@机器人:彩色/黑白
            机器人:TEXTSIZE =24sp/&GT;

        &LT;的LinearLayout
            机器人:layout_width =match_parent
            机器人:layout_height =WRAP_CONTENT
            机器人:layout_alignParentBottom =真
            机器人:layout_below =@ ID / card_view_title
            机器人:layout_centerHorizo​​ntal =真
            机器人:重力=中心&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 Buttons. 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆