www.2527.com_澳门新葡8455手机版_新京葡娱乐场网址_
做最好的网站

RecyclerView的Item的单击事件,RecycleView的粗略利用

2019-09-28 10:47 来源:未知

来得效果

www.2527.com 1

RecyclerView 的各样Item的点击事件并从未像ListView同样封装在组件中,需求Item的单击事件时就须求团结去贯彻,在Adapter中为RecyclerView增加单击事件参谋如下:

RecyclerView的使用情势请参见:RecyclerView的简练利用

www.2527.com 2

来源

第一步:

在RecyclerView的Adapyer中定义单击事件的回调接口:

/** * 定义RecyclerView选项单击事件的回调接口 */public interface OnItemClickListener{    //参数(父组件,当前单击的View,单击的View的位置,数据)    void onItemClick(RecyclerView parent,View view, int position, String data);}

原来的书文出自王艳涛的特辑转发请评释出处!

RecyclerView 是Android L版本中新增进的贰个用来代表ListView的SDK,它的布帆无恙与可替代性比listview越来越好。接下来通过一种类的稿子解说如何行使RecyclerView,通透到底遗弃ListView.

第二步:

在RecyclerView的Adapyer中宣示该接口,并提供setter方法:

private OnItemClickListener onItemClickListener;public void setOnItemClickListener(OnItemClickListener onItemClickListener){    this.onItemClickListener = onItemClickListener;}

概述

正文主要介绍android中RecyclerView的Item点击、长按事件的响应及上海滑稽剧团加载功用封装。从前的几篇作品从RecyclerView.Adapter的角度,先介绍了RecyclerView.Adapter的封装和效果扩充,然后同盟RecyclerView、SwipeRefreshLayout达成上海好笑剧团加载、下拉刷新操作。从上海好笑剧团加载、下拉刷新一文中,能够看出一贯运用RecyclerView时有多少个地方的困顿:

  1. RecyclerView未有提供Item的点击、长按事件,需求活动达成。
  2. 假如软件中RecyclerView的行使比比较多,供给上海好笑剧团加载的情景也正如多,假如不开展打包,那么每趟上海滑稽剧团加载时,都要写上一大段OnScrollListener重复代码,影响代码阅读。至于下拉刷新,是依靠SwipeRefreshLayout完毕的,不须要封装在RecyclerView中。

介绍

RecyclerView与ListView原理是看似的:都是仅仅维护一些些的View况兼能够显得大量的数目集。RecyclerView用以下三种办法简化了数码的来得和拍卖:

  • 行使LayoutManager来明显每贰个item的排列格局。
  • 为增加和删除项目提供暗许的卡通效果。
  • 艾达pter:使用RecyclerView以前,你必要三个承袭自RecyclerView.Adapter的适配器,效能是将数据与每四个item的分界面实行绑定。
  • LayoutManager:用来明确每四个item如何实行排列摆放,什么日期展示和隐形。回收或录取多个View的时候,LayoutManager会向适配器央求新的数目来替换旧的数目,这种机制幸免了成立过多的View和高频的调用findViewById方法(与ListView原理类似)。

脚下SDK中提供了两种自带的LayoutManager:

  • LinearLayoutManager
  • GridLayoutManager
  • StaggeredGridLayoutManager

第三步:

在RecyclerView的Adapyer类达成View.OnClickListener接口,同等对待写onClick(View view)方法,然后设置给接口的风浪监听:

public class RvAdapter1 extends RecyclerView.Adapter<RvAdapter1.DataViewHolder> implements View.OnClickListener{    ...    view.setOnClickListener(this);//设置监听器    ...    @Override    public void onClick(View view) {        //根据RecyclerView获得当前View的位置        int position = recyclerView.getChildAdapterPosition;        //程序执行到此,会去执行具体实现的onItemClick()方法        if (onItemClickListener!=null){            onItemClickListener.onItemClick(recyclerView,view,position,mList.get);        }    }    ...}

Item响应点击、长按事件

贯彻RecyclerView的Item响应点击、长按事件能够有三种思路:

  1. 从RecyclerView本身出发,借助GestureDetector类,Item的点击、长按事件,举办响应;
  2. 从上篇小说RecyclerView.Adapter的封装的BaseAdapter出发,借助BaseAdapter可以给Item内部控件加多事件监听的力量,向Item的根部局增多贰个事变监听,进而到达使Item响应单击、长按事件;

率先节、轻巧的RecycleView的运用办法

第四步:

在MainActivity中通过艾达pter设置各样Item的单击事件:

adapter.setOnItemClickListener(new RvAdapter1.OnItemClickListener() {    @Override    public void onItemClick(RecyclerView parent, View view, int position, String data) {        Toast.makeText(MainActivity.this, data, Toast.LENGTH_SHORT).show;

重视GestureDetector类完结点击、长按事件监听

参考ListView的setOnClickListener()的选取办法,当想让RecyclerView的Item能够监听点击、长按事件时,须要贯彻三个监听接口并给RecyclerView传进去,封装后的利用办法应该如上边所示:

//单击事件
baseRecyclerView.setOnItemClickListener(new BaseRecyclerView.OnItemClickListener() {
           @Override
           public void onItemClick(View view, BaseHolder baseHolder, int position) {
               //回调的时候能够传回点击的Item的view、holder、位置三个信息
           }
       });
//长按事件
recyclerView.setOnItemLongClickListener(new BaseRecyclerView.OnItemLongClickListener(){
           @Override
           public void onItemLongClick(View view, BaseHolder baseHolder, int position) {
               //回调的时候能够传回点击的Item的view、holder、位置三个信息
           }
       });

据此BaseRecyclerView类中,应该具备:

  1. 饱含onItemClick()方法的OnItemClickListener接口的定义;
  2. 含有onItemLongClick()方法的OnItemClickLOngListener接口的概念;
  3. OnItemClickListener接口类型的引用变量(用于收纳传入的OnItemClickListener);
  4. OnItemClickLongListener接口类型的援用变量(用于吸收接纳传入的OnItemClickLongListener);
  5. 能够分辨客商点击、长按并开展回调的靶子,
  6. setOnItemClickListener方法
  7. setOnItemLongClickListener方法。

代码如下所示。

public class BaseRecyclerView extends RecyclerView {
    //OnItemClickListener接口类型的引用变量
    private OnItemClickListener onItemClickListener;
    //OnItemClickLongListener接口类型的引用变量
    private OnItemLongClickListener onItemLongClickListener;
    //能够识别用户点击、长按能够进行回调的对象
    private GestureDetectorCompat gestureDetectorCompat;
    //重载的构造函数
    public BaseRecyclerView(Context context) {
        super(context);
        //获取GestureDetectorCompat实例
        this.gestureDetectorCompat = getGestureDetectorCompat();
    }

    public BaseRecyclerView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        this.gestureDetectorCompat = getGestureDetectorCompat();
    }

    public BaseRecyclerView(Context context, @Nullable AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        this.gestureDetectorCompat = getGestureDetectorCompat();
    }
    //赋值监听器
    public void setOnItemClickListener(OnItemClickListener onItemClickListener){
        this.onItemClickListener = onItemClickListener;
    }

    public void setOnItemLongClickListener(OnItemLongClickListener onItemLongClickListener){
        this.onItemLongClickListener = onItemLongClickListener;
    }
    //接口定义
    public interface OnItemClickListener{
        void onItemClick(View view, BaseHolder baseHolder, int position);
    }

    public interface OnItemLongClickListener{
        void onItemLongClick(View view, BaseHolder baseHolder, int position);
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent e) {
        gestureDetectorCompat.onTouchEvent(e);
        return false;
    }
    //获取GestureDetectorCompat实例
    public GestureDetectorCompat getGestureDetectorCompat(){

        return new GestureDetectorCompat(getContext(),
                new GestureDetector.SimpleOnGestureListener(){
                    @Override
                    public boolean onSingleTapUp(MotionEvent e) {
                      //判断为单击事件
                        View childView = findChildViewUnder(e.getX(), e.getY());
                        if (childView != null &&
                                onItemClickListener !=null){
                                  //回调单击事件
                            onItemClickListener.onItemClick(childView,
                                    (BaseHolder)getChildViewHolder(childView),
                                    getChildAdapterPosition(childView));
                        }
                        return true;
                    }

                    @Override
                    public void onLongPress(MotionEvent e) {
                      //判断为长按事件
                        View childView = findChildViewUnder(e.getX(), e.getY());
                        if (childView != null && onItemLongClickListener !=null){
                          //回调长按事件
                            onItemLongClickListener.onItemLongClick(childView,
                                    (BaseHolder)getChildViewHolder(childView),
                                    getChildAdapterPosition(childView));
                        }
                    }
                });
    }
}

1. 加上信任

在ASbuild.gradle中增添依赖,然后一并一下就足以引进依赖包:

dependencies {
...
compile 'com.android.support:recyclerview-v7:21.0. '
}

参谋代码

借助BaseAdapter达成单击、长按事件监听

这种艺术比较轻松,在BaseAdapter中加进一个setOnClickListener()方法,让BaseAdapter持有多个View.OnClickListener的引用,然后经过BaseAdapter中onBind()方法中BaseHolder参数的setOnClickListener(int viewId, View.OnClickListener listener)方法,将监听器绑定到Item的根部局上(须要为Item的根部局赋值二个id)。

BaseAdapter改进:

//增加一个View.OnClickListener变量
 View.OnClickListener onClickListener;
//增加一个setOnClickListener()
public void setOnClickListener(View.OnClickListener onClickListener){
    this.onClickListener = onClickListener;
}

子类艾达pter供给专心将onClickListener传给holder

@Override
   public void onBind(BaseHolder holder, final Contact contact, int position) {
       holder.setOnClickListener(R.id.item, onClickListener);
   }

行使格局:

adapter.setOnClickListener(new View.OnClickListener(){
  @Override
  public void onClick(View v) {
    //单击事件的回调
  }
});

2. 编纂代码

增添完注重之后,就起来写代码了,与ListView用法类似,也是先在xml布局文件中创立叁个RecyclerView的布局:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">
    <android.support.v7.widget.RecyclerView
        android:id="@ id/my_recycler_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:scrollbars="vertical"/>
</RelativeLayout>

始建完布局之后在MainActivity中取得这一个RecyclerView,并注明LayoutManager与Adapter,代码如下:

mRecyclerView = (RecyclerView)findViewById(R.id.my_recycler_view);
//创建默认的线性LayoutManager
mLayoutManager = new LinearLayoutManager(this);
mRecyclerView.setLayoutManager(mLayoutManager);
//如果可以确定每个item的高度是固定的,设置这个选项可以提高性能
mRecyclerView.setHasFixedSize(true);
//创建并设置Adapter
mAdapter = newMyAdapter(getDummyDatas());
mRecyclerView.setAdapter(mAdapter);

www.2527.com,接下去的标题正是Adapter的开创:

public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> {
    public String[] datas = null;
    public MyAdapter(String[] datas) {
        this.datas = datas;
    }
    //创建新View,被LayoutManager所调用
    @Override
    public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
        View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.item,viewGroup,false);
        ViewHolder vh = new ViewHolder(view);
        return vh;
    }
    //将数据与界面进行绑定的操作
    @Override
    public void onBindViewHolder(ViewHolder viewHolder, int position) {
        viewHolder.mTextView.setText(datas[position]);
    }
    //获取数据的数量
    @Override
    public int getItemCount() {
        return datas.length;
    }
    //自定义的ViewHolder,持有每个Item的的所有界面元素
    public static class ViewHolder extends RecyclerView.ViewHolder {
        public TextView mTextView;
        public ViewHolder(View view){
        super(view);
            mTextView = (TextView) view.findViewById(R.id.text);
        }
    }
}
Adapter
/** * Created by jzman on 2017/5/13 0013. * RecycleView的Adapter */public class RvAdapter1 extends RecyclerView.Adapter<RvAdapter1.DataViewHolder> implements View.OnClickListener{    private Context mContext;    private RecyclerView recyclerView;    private ArrayList<String> mList;    public RvAdapter1() {}    public RvAdapter1(Context mContext, ArrayList<String> mList) {        this.mContext = mContext;        this.mList = mList;    }    /**     * 用于创建ViewHolder     * @param parent     * @param viewType     * @return     */    @Override    public DataViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {        View view = LayoutInflater.from.inflate(R.layout.item,null);        view.setOnClickListener(this);        //使用代码设置宽高(xml布局设置无效时)        view.setLayoutParams(new ViewGroup.LayoutParams(                ViewGroup.LayoutParams.MATCH_PARENT,                ViewGroup.LayoutParams.WRAP_CONTENT));        DataViewHolder holder = new DataViewHolder;        return holder;    }    /**     * 绑定数据     * @param holder     * @param position     */    @Override    public void onBindViewHolder(DataViewHolder holder, int position) {        holder.tv_data.setText(mList.get);    }    /**     * 选项总数     * @return     */    @Override    public int getItemCount() {        return mList.size();    }    @Override    public void onClick(View view) {        //根据RecyclerView获得当前View的位置        int position = recyclerView.getChildAdapterPosition;        //程序执行到此,会去执行具体实现的onItemClick()方法        if (onItemClickListener!=null){            onItemClickListener.onItemClick(recyclerView,view,position,mList.get);        }    }    /**     * 创建ViewHolder     */    public static class DataViewHolder extends RecyclerView.ViewHolder{        TextView tv_data;        public DataViewHolder(View itemView) {            super;            tv_data =  itemView.findViewById(R.id.tv_recycle);        }    }    private OnItemClickListener onItemClickListener;    public void setOnItemClickListener(OnItemClickListener onItemClickListener){        this.onItemClickListener = onItemClickListener;    }    /**     * 定义RecyclerView选项单击事件的回调接口     */    public interface OnItemClickListener{        //参数(父组件,当前单击的View,单击的View的位置,数据)        void onItemClick(RecyclerView parent,View view, int position, String data);    }    /**     *   将RecycleView附加到Adapter上     */    @Override    public void onAttachedToRecyclerView(RecyclerView recyclerView) {        super.onAttachedToRecyclerView(recyclerView);        this.recyclerView= recyclerView;    }    /**     *   将RecycleView从Adapter解除     */    @Override    public void onDetachedFromRecyclerView(RecyclerView recyclerView) {        super.onDetachedFromRecyclerView(recyclerView);        this.recyclerView = null;    }}

对将上海滑稽剧团加载事件响应实行打包

在上面BaseRecyclerView代码的根底上开展革新

//定义一个OnLoadableListener监听接口
public interface OnLoadableListener{
    void load();
}
//增加一个OnLoadableListener引用变量
private OnLoadableListener onLoadableListener;
//增加一个赋值OnLoadableListener的setter方法
public void setOnLoadableListener(OnLoadableListener onLoadableListener){
    this.onLoadableListener = onLoadableListener;
}
//增加一个将接收到的OnLoadableListener绑定到当前BaseRecyclerView上的函数
    public void addOnLoadableListener(OnLoadableListener onLoadableListener){
        addOnScrollListener(new RecyclerView.OnScrollListener() {
            @Override
            public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
                super.onScrolled(recyclerView, dx, dy);
                //使用的封装的BaseAdapter适配器
                if (((LinearLayoutManager)getLayoutManager()).
                        findLastVisibleItemPosition() == getAdapter().getItemCount()-1){
                    //执行加载回调操作
                    onLoadableListener.load();
                }
            }
        });
    }

3. 运行

写完这几个代码那些例子不仅可以跑起来了。从例子也能够看出来,RecyclerView的用法并不如ListView复杂,反而更加灵敏好用,它将数据、排列方式、数据的呈现格局都划分开来,由此可定制型,自定义的花样也非常多,特别灵活。

MainActivity
/** * Created by jzman on 2017/5/13 0013. */public class MainActivity extends AppCompatActivity {    private RecyclerView rv;    RvAdapter1 adapter;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        rv = (RecyclerView) findViewById;        //设置布局管理器//        rv.setLayoutManager(new LinearLayoutManager;//线性        rv.setLayoutManager(new GridLayoutManager(this,4));//线性//        rv.setLayoutManager(new StaggeredGridLayoutManager(4,StaggeredGridLayoutManager.VERTICAL));//线性        adapter = new RvAdapter1(this,initData;        adapter.setOnItemClickListener(new RvAdapter1.OnItemClickListener() {            @Override            public void onItemClick(RecyclerView parent, View view, int position, String data) {                Toast.makeText(MainActivity.this, data, Toast.LENGTH_SHORT).show();            }        });        rv.setAdapter;    }    public static ArrayList<String> initData(){        ArrayList<String> arrayList = new ArrayList<>();        for (int i=0;i<50;i  ){            arrayList.add("第" i "条数据");        }        return arrayList;    }}

行使办法

recyclerView.setOnLoadableListener(new BaseRecyclerView.OnLoadableListener() {
    @Override
    public void load() {
      if (!isLoading) {
        isLoading = true;
        //加载操作
        //……
        isLoading = false;
      }
    }
});

横向布局

倘诺想要一个横向的List只要设置LinearLayoutManager如下就行,注意要表明mLayoutManager的品种是LinearLayoutManager并非父类LayoutManager:

mLayoutManager.setOrientation(LinearLayoutManager.HORIZONTAL);

Grid布局

借使想要八个Grid布局的列表,只要注解LayoutManager为GridLayoutManager就可以:

mLayoutManager = new GridLayoutManager(context,columNum);
mRecyclerView.setLayoutManager(mLayoutManager);

在意,在Grid布局中也足以安装列表的Orientation属性,来落实横向和纵向的Grid布局。

瀑布流布局

瀑布流就应用StaggeredGridLayoutManager吧,具体方法与地点类似,就不做牵线啦。

总结

本节介绍的是八个最最简易的RecyclerView的施用方法,前边将介绍一些越来越尖端的用法。

其次节、RecyclerView的高级方法

当使用了一段时间的RecyclerView,发掘为其种种增添点击事件并从未ListView那么轻巧,像ListView直接加个OnItemClickListener就行了。事实上大家不要把RecyclerView当做ListView的多个进级版,希望我们把她当做一个器皿,同一时候中间满含了好些个例外的Item,它们得以以不一致方法排列组合,极其灵活,点击情势你能够根据你本人的心愿举行落到实处。
本节珍视教学如何为RecyclerView增加点击事件, 并简要介绍怎么样实行Item扩大删除。

1. 增长条约点击事件、长按事件

上一节中咱们讲了何等运用RecyclerView的Adpater,其实大家会意识,Adapter是增加点击事件二个很好的地点,里面是结构布局等View的重点场馆,也是数量和布局进行绑定的地方。首先我们在Adapter中开创贰个贯彻点击接口,当中view是最近的条规,position是点击的Item,因为大家想清楚自家点击的区域部分的数码是怎样,以便笔者下一步举行操作:

    /**
     * ItemClick的回调接口
     */
    public interface OnItemClickListener {
        void onItemClick(View view, int position);
    }

    /**
     * ItemLongClick的回调接口
     */
    public interface OnItemLongClickListener {
        void onItemLongClick(View view, int position);
    }

概念完接口,增多接口和设置Adapter接口的诀窍:

    /**
     * 设置条目点击监听
     * @param onItemClickListener
     */
    public void setOnItemClickListener(OnItemClickListener onItemClickListener) {
        this.onItemClickListener = onItemClickListener;
    }

    /**
     * 设置条目长按监听
     * @param onItemLongClickListener
     */
    public void setOnItemLongClickListener(OnItemLongClickListener onItemLongClickListener) {
        this.onItemLongClickListener = onItemLongClickListener;
    }

那么这些接口用在如哪处方啊?如下代码所示,大家为Adapter达成OnClickListener方法:

    /**
     * 创建新View,被LayoutManager所调用*
     * @param parent
     * @param viewType
     * @return
     */
    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_recycle, parent, false);
        ViewHolder vh = new ViewHolder(view);
        return vh;
    }

    /**
     * 将数据与界面进行绑定的操作
     */
    @Override
    public void onBindViewHolder(final MyAdapter.ViewHolder holder, final int position) {
        holder.text.setText(datas.get(position));
        // 如果设置了回调,则设置点击事件
        if (onItemClickListener != null) {
            holder.itemView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    onItemClickListener.onItemClick(holder.itemView, position);
                }
            });
        }
        // 如果设置了回调,则设置长按点击事件
        if (onItemLongClickListener != null) {
            holder.itemView.setOnLongClickListener(new View.OnLongClickListener() {
                @Override
                public boolean onLongClick(View view) {
                    onItemLongClickListener.onItemLongClick(holder.itemView, position);
                    return true; // 如果return false,会继续执行点击事件
                }
            });
        }
    }

    @Override
    public int getItemCount() {
        return datas.size();
    }

做完那么些业务,大家就足以在Activity或其余地点为RecyclerView增多项目点击事件了,如在MainActivity中:

        // 创建并设置Adapter
        adapter = new MyAdapter(datas);
        recyclerView.setAdapter(adapter);

        // item的点击监听
        adapter.setOnItemClickListener(new MyAdapter.OnItemClickListener() {
            @Override
            public void onItemClick(View view, int position) {

                Snackbar.make(recyclerView, "position="   position, Snackbar.LENGTH_SHORT)
                        .setAction("点我", new View.OnClickListener() {
                            @Override
                            public void onClick(View view) {
                                Toast.makeText(MainActivity.this, "我让你点你就点啊,你是不是傻!", Toast.LENGTH_SHORT).show();
                            }
                        })
                        .show();
            }
        });

        adapter.setOnItemLongClickListener(new MyAdapter.OnItemLongClickListener() {
            @Override
            public void onItemLongClick(View view, int position) {
                Snackbar.make(recyclerView, "这是长按事件哦--Position="   position, Snackbar.LENGTH_SHORT).show();
            }
        });

2. 加上删减数据

曾经在ListView在那之中,大家假诺修改后数据用Adapter的notifyDatasetChange一下就足以立异分界面。然则在RecyclerView中还应该有一部分更加高等的用法:

增加数据:

/**
     * 添加条目
     * @param position
     */
    public void addData(int position) {
        datas.add(position, "Insert One");
        notifyItemInserted(position);
    }

去除数据:

    /**
     * 删除条目
     * @param position
     */
    public void removeData(int position) {
        datas.remove(position);
        notifyItemRemoved(position);
    }

值得注意的是RecyclerView的丰盛删除都以有暗中认可的动画片效果的,若无意义可以加上如下代码:

mRecyclerView.setItemAnimator(newDefaultItemAnimator());

当然啦你也得以协和定义你本人的Animator

TAG标签:
版权声明:本文由澳门新葡8455手机版发布于www.2527.com,转载请注明出处:RecyclerView的Item的单击事件,RecycleView的粗略利用