RecyclerView下拉刷新上拉加载(一) http://blog.csdn.net/baiyuliang2013/article/details/51506036

RecyclerView下拉刷新上拉加载(二) http://blog.csdn.net/baiyuliang2013/article/details/51506354

RecyclerView嵌套RecyclerView http://blog.csdn.net/baiyuliang2013/article/details/51518868

前两篇讲了RecyclerView下拉刷新上拉加载普通实现,以及动画实现,但在使用时对适配器数据的填充比较原始,且RecyclerView并没有像ListView那样自带的item点击事件和长按事件,所以如果不做点什么的话,每次填充数据还不要麻烦死?!因此,这篇文章将讲解如何封装一个BaseAdapter使得每次使用时,对数据的填充,以及对item的点击,长按事件,甚至于item中的子View的点击事件变得简单起来!

还是先上两个图,看下效果:

第一张图就是一普通String的列表,只包含了item的点击和长按事件,第二张图,则是一个model列表,包含了item的点击,长按,以及子View的赞和评论(模仿qq空间说说)的点击事件!

在封装Adapter时要有一个基础思想,就是我们想要实现一个怎样的效果,或者说我们在调用时,想要简单到什么程度?然后再结合Listview的adapter内部流程,得出了最基本的几个点:

  • 数据源:无论你的model是什么,我都可以随意传进Adapter对吧;
  • item点击和长按事件:统一设置一个对外接口,不必每次都要在adapter重写一遍吧;
  • item中子View的点击事件:就像第二张图,常见的需求吧;

注意: 以上所有的回调都是在Activity中进行的,而不是在Adapter中!

本文主要就是实现了以上三点,看似没什么,但其实在使用时会省掉不少力气!当然,你也可以根据自己的需求,在BaseAdapter中继续写一些简化操作步骤的方法,本文只是对于最常见的操作做的一个封装!

BaseAdapter:

package com.byl.recyclerview.view;

import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import java.util.List;

/**
 * BaseAdapter
 * Created by baiyuliang on 2016-5-27.
 */
public class BaseAdapter<T extends RecyclerView.ViewHolder> extends RecyclerView.Adapter<T> {

    public Context context;//上下文
    public List<Object> listDatas;//数据源
    public LayoutInflater mInflater;
    public OnViewClickListener onViewClickListener;//item子view点击事件
    public OnItemClickListener onItemClickListener;//item点击事件
    public OnItemLongClickListener onItemLongClickListener;//item长按事件

    public BaseAdapter(Context context, List<Object> listDatas) {
        init(context,listDatas);
    }

    /**
     * 如果item的子View有点击事件,可使用该构造方法
     * @param context
     * @param listDatas
     * @param onViewClickListener
     */
    public BaseAdapter(Context context, List<Object> listDatas, OnViewClickListener onViewClickListener) {
        init(context,listDatas);
        this.onViewClickListener = onViewClickListener;
    }

    /**
     * 初始化
     * @param context
     * @param listDatas
     */
    void init(Context context, List<Object> listDatas){
        this.context = context;
        this.listDatas = listDatas;
        this.mInflater = LayoutInflater.from(context);
    }

    @Override
    public T onCreateViewHolder(ViewGroup parent, int viewType) {
        return null;
    }

    @Override
    public void onBindViewHolder(T holder, final int position) {
        holder.itemView.setOnClickListener(new View.OnClickListener() {//item点击事件
            @Override
            public void onClick(View v) {
                if (onItemClickListener != null) {
                    onItemClickListener.onItemClick(position);
                }
            }
        });
        holder.itemView.setOnLongClickListener(new View.OnLongClickListener() {//item长按事件
            @Override
            public boolean onLongClick(View v) {
                if (onItemLongClickListener != null) {
                    onItemLongClickListener.onItemLongClick(position);
                }
                return true;
            }
        });
    }

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

    /**
     * item中子view的点击事件(回调)
     */
    public interface OnViewClickListener {
        /**
         * @param position item position
         * @param viewtype 点击的view的类型,调用时根据不同的view传入不同的值加以区分
         */
        void onViewClick(int position,int viewtype);
    }

    /**
     * item点击事件
     */
    public interface OnItemClickListener {
        void onItemClick(int position);
    }

    /**
     * item长按事件
     */
    public interface OnItemLongClickListener {
        void onItemLongClick(int position);
    }

    /**
     * 设置item点击事件
     * @param onItemClickListener
     */
    public void setOnItemClickListener(OnItemClickListener onItemClickListener) {
        this.onItemClickListener = onItemClickListener;
    }

    /**
     * 设置item长按事件
     * @param onItemLongClickListener
     */
    public void setOnItemLongClickListener(OnItemLongClickListener onItemLongClickListener) {
        this.onItemLongClickListener = onItemLongClickListener;
    }

}

其中有两个构造方法,注释写的非常清楚,根据自己的需求,在new Adapter时选取不同的构造方法:

 public BaseAdapter(Context context, List<Object> listDatas) {
        init(context,listDatas);
    }
/**
     * 如果item的子View有点击事件,可使用该构造方法
     * @param context
     * @param listDatas
     * @param onViewClickListener
     */
    public BaseAdapter(Context context, List<Object> listDatas, OnViewClickListener onViewClickListener) {
        init(context,listDatas);
        this.onViewClickListener = onViewClickListener;
    }

好了,接下来我们看下整个demo的结构:

首先看Activity1中TextAdapter实现:

/**
 * Created by baiyuliang on 2016-5-27.
 */
public class TextAdapter extends BaseAdapter<TextAdapter.MyViewHolder> {

    public TextAdapter(Context context, List<Object> listDatas) {
        super(context, listDatas);
    }

    @Override
    public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        return new MyViewHolder(mInflater.inflate(R.layout.item_text, parent, false));
    }

    @Override
    public void onBindViewHolder(MyViewHolder holder, final int position) {
        super.onBindViewHolder(holder, position);
        String text = (String) listDatas.get(position);//转换
        holder.tv.setText(text);//填充数据
    }

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

    class MyViewHolder extends RecyclerView.ViewHolder {

        TextView tv;

        public MyViewHolder(View view) {
            super(view);
            tv = (TextView) view.findViewById(R.id.tv);
        }
    }
}

Activity1中的调用:

 private void initRecyclerView() {
        recyclerView = (PullRecyclerView) findViewById(R.id.recyclerView);
        recyclerView.setOnRefreshListener(this);
        recyclerView.setLayoutManager(new LinearLayoutManager(this));
        textAdapter = new TextAdapter(this, mDatas);
        textAdapter.setOnItemClickListener(this);
        textAdapter.setOnItemLongClickListener(this);
        recyclerView.setAdapter(textAdapter);
    }

    @Override
    public void onItemClick(int position) {
        Toast.makeText(Activity1.this, "点击-position>>" + position, Toast.LENGTH_SHORT).show();
    }

    @Override
    public void onItemLongClick(int position) {
        Toast.makeText(Activity1.this, "长按-position>>" + position, Toast.LENGTH_SHORT).show();
    }

接着看Activity2中的InfoAdapter实现:

/**
 * Created by baiyuliang on 2016-5-27.
 */
public class InfoAdapter extends BaseAdapter<InfoAdapter.MyViewHolder> {

    public InfoAdapter(Context context, List<Object> listDatas, OnViewClickListener onViewClickListener) {
        super(context, listDatas, onViewClickListener);
    }

    @Override
    public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        return new MyViewHolder(mInflater.inflate(R.layout.item_info, parent, false));
    }

    @Override
    public void onBindViewHolder(MyViewHolder holder, final int position) {
        super.onBindViewHolder(holder, position);
        InfoBean infoBean = (InfoBean) listDatas.get(position);//转换
        holder.tv.setText(infoBean.getText());//填充数据
        holder.iv_z.setOnClickListener(new ViewClikListener(onViewClickListener, position, 1));//赞 viewtype=1代表赞点击事件
        holder.iv_pl.setOnClickListener(new ViewClikListener(onViewClickListener, position, 2));//评论 viewtype=2代表评论点击事件
    }

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

    class MyViewHolder extends RecyclerView.ViewHolder {
        TextView tv;//内容
        ImageView iv_z, iv_pl;//赞,评论

        public MyViewHolder(View view) {
            super(view);
            tv = (TextView) view.findViewById(R.id.tv);
            iv_z = (ImageView) view.findViewById(R.id.iv_z);
            iv_pl = (ImageView) view.findViewById(R.id.iv_pl);
        }
    }

    /**
     * view的点击事件
     */
    class ViewClikListener implements View.OnClickListener {

        OnViewClickListener onViewClickListener;
        int position;
        int viewtype;

        public ViewClikListener(OnViewClickListener onViewClickListener, int position, int viewtype) {
            this.onViewClickListener = onViewClickListener;
            this.position = position;
            this.viewtype = viewtype;
        }

        @Override
        public void onClick(View v) {
            onViewClickListener.onViewClick(position, viewtype);
        }
    }

}

Activity2中的调用:

 private void initRecyclerView() {
        recyclerView = (PullRecyclerView) findViewById(R.id.recyclerView);
        recyclerView.setOnRefreshListener(this);
        recyclerView.setLayoutManager(new LinearLayoutManager(this));
        infoAdapter = new InfoAdapter(this, mDatas, this);
        infoAdapter.setOnItemClickListener(this);
        infoAdapter.setOnItemLongClickListener(this);
        recyclerView.setAdapter(infoAdapter);
    }

    /**
     * 子View点击事件
     *
     * @param position item position
     * @param viewtype 点击的view的类型,调用时根据不同的view传入不同的值加以区分
     */
    @Override
    public void onViewClick(int position, int viewtype) {
        switch (viewtype) {
            case 1://赞
                Toast.makeText(Activity2.this, "赞-position>>" + position, Toast.LENGTH_SHORT).show();
                break;
            case 2://评论
                Toast.makeText(Activity2.this, "评论-position>>" + position, Toast.LENGTH_SHORT).show();
                break;
        }
    }

    /**
     * item点击事件
     *
     * @param position
     */
    @Override
    public void onItemClick(int position) {
        Toast.makeText(Activity2.this, "点击-position>>" + position, Toast.LENGTH_SHORT).show();
    }

    /**
     * item长按事件
     *
     * @param position
     */
    @Override
    public void onItemLongClick(int position) {
        Toast.makeText(Activity2.this, "长按-position>>" + position, Toast.LENGTH_SHORT).show();
    }

基本跟Listview没什么区别了,对于不同类型的Adapter只需复制粘贴即可,当然,本例中并没有封装添加或者删除动画以及分割线等等用户体验方面的代码,只是做了最基础的封装!你可能会说,图中明明有分割线,这是怎么弄的?哈哈,对于RecyclerView设置分割线有两种做法:一种是在item布局xml中直接在顶部或者底部放条线,或者最外层设置一下paddingTop或paddingBottom即可;第二种比较优雅的做法就是重写ItemDecoration类,并调用addItemDecoration()方法;根据自己的喜好或者需求吧,哪种方便按哪种来!

最后,再结合上两篇实现的下拉刷新上拉加载(自己可以再封装一些动画之类的操作或其它功能),将会满足普通项目开发中的大部分需求了!

本例中对第一篇中的代码做了部分优化,并增加了几个设置方法:

//        recyclerView.setCanScrollAtRereshing(true);//设置正在刷新时是否可以滑动,默认不可滑动
//        recyclerView.setCanPullDown(false);//设置是否可下拉
//        recyclerView.setCanPullUp(false);//设置是否可上拉

可根据自己的需求进行相应设置!

ASdemo下载地址:http://download.csdn.net/detail/baiyuliang2013/9533101

RecyclerView下拉刷新上拉加载(三)—对Adapter的封装的更多相关文章

  1. Android 下拉刷新上啦加载SmartRefreshLayout + RecyclerView

    在弄android刷新的时候,可算是耗费了一番功夫,最后发觉有现成的控件,并且非常好用,这里记录一下. 原文是 https://blog.csdn.net/huangxin112/article/de ...

  2. SwipeRefreshLayout实现下拉刷新上滑加载

    1. 效果图 2.RefreshLayout.java package myapplication.com.myapplication; import android.content.Context; ...

  3. 移动端下拉刷新上拉加载-mescroll.js插件

    最近无意间看到有这么一个上拉刷新下拉加载的插件 -- mescroll.js,个人感觉挺好用的,官网地址是:http://www.mescroll.com 然后我就看了一下文档,简单的写了一个小dem ...

  4. 带你实现开发者头条APP(五)--RecyclerView下拉刷新上拉加载

    title: 带你实现开发者头条APP(五)--RecyclerView下拉刷新上拉加载 tags: -RecyclerView,下拉刷新,上拉加载更多 grammar_cjkRuby: true - ...

  5. RecyclerView下拉刷新上拉加载(二)

    listview下拉刷新上拉加载扩展(一) http://blog.csdn.net/baiyuliang2013/article/details/50252561 listview下拉刷新上拉加载扩 ...

  6. RecyclerView下拉刷新上拉加载(一)

    listview下拉刷新上拉加载扩展(一) http://blog.csdn.net/baiyuliang2013/article/details/50252561 listview下拉刷新上拉加载扩 ...

  7. MaterialRefreshLayout+ListView 下拉刷新 上拉加载

    效果图是这样的,有入侵式的,非入侵式的,带波浪效果的......就那几个属性,都给出来了,自己去试就行. 下拉刷新 上拉加载 关于下拉刷新-上拉加载的效果,有许许多多的实现方式,百度了一下竟然有几十种 ...

  8. 自定义ListView下拉刷新上拉加载更多

    自定义ListView下拉刷新上拉加载更多 自定义RecyclerView下拉刷新上拉加载更多 Listview现在用的很少了,基本都是使用Recycleview,但是不得不说Listview具有划时 ...

  9. ListView实现Item上下拖动交换位置 并且实现下拉刷新 上拉加载更多

    ListView实现Item上下拖动交换位置  并且实现下拉刷新  上拉加载更多 package com.example.ListViewDragItem; import android.app.Ac ...

随机推荐

  1. hdu 5119(2014北京)

    题意: 随机选择一个数,如果后面有比他小的就进行交换,直到没有为止(算一轮).求多少轮后为递增序列 思路: 倒着找,如果有比经过的最小数大的,ans+1 #include <iostream&g ...

  2. bzoj1071[SCOI2007]组队

    1071: [SCOI2007]组队 Time Limit: 3 Sec  Memory Limit: 128 MBSubmit: 2472  Solved: 792[Submit][Status][ ...

  3. hdu 5600 BestCoder Round #67 (div.2)

    N bulbs  Accepts: 275  Submissions: 1237  Time Limit: 10000/5000 MS (Java/Others)  Memory Limit: 655 ...

  4. bzoj3262陌上花开 cdq分治

    3262: 陌上花开 Time Limit: 20 Sec  Memory Limit: 256 MBSubmit: 2794  Solved: 1250[Submit][Status][Discus ...

  5. Java后缀数组-求sa数组

    后缀数组的一些基本概念请自行百度,简单来说后缀数组就是一个字符串所有后缀大小排序后的一个集合,然后我们根据后缀数组的一些性质就可以实现各种需求. public class MySuffixArrayT ...

  6. WebDNN:Web浏览器上最快的DNN执行框架

    WebDNN:Web浏览器上最快的DNN执行框架 为什么需要WebDNN? 深层神经网络(DNN)在许多应用中受到越来越多的关注. 然而,它需要大量的计算资源,并且有许多巨大的过程来设置基于执行环境的 ...

  7. postgresql 安装使用

    www.postgresql.org去下载你需要的版本,我下载的9.6.8 安装过程中会让你输入一次密码,其余的默认就ok 默认超级用户名postgres 打开 pgadmin4,我们将语言改为中文会 ...

  8. Python小代码_13_生成两个参数的最小公倍数和最大公因数

    def demo(m, n): if m > n: m, n = n, m p = m * n while m != 0: r = n % m n = m m = r return (int(p ...

  9. CentOS7 YUM 安装NGINX

    1.先添加源: nano /etc/yum.repos.d/nginx.repo 把下边这段代码添加到nginx.repo中去.[nginx] name=nginx repo baseurl=http ...

  10. Node.js 网络

    稳定性: 3 - 稳定 net 模块提供了异步网络封装,它包含了创建服务器/客户端的方法(调用 streams).可以通过调用 require('net') 包含这个模块. net.createSer ...