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. kafka快速入门

    一.kafka简介 kafka,ActiveMQ,RabbitMQ是当今最流行的分布式消息中间件,其中kafka在性能及吞吐量方面是三者中的佼佼者,不过最近查阅官网时,官方与它的定义为一个分布式流媒体 ...

  2. Java连接FTP成功,但是上传是失败,报错:Connected time out

    Java代码在本机上传文件到FTP服务器的时候成功,但是部署到测试服务器的时候出现,连接FTP成功但是上传失败,并且报Connected time out错误: 测试服务器和FTP服务都在阿里云上:( ...

  3. 你知道src、url、href的全称吗?

    url:Uniform Resource Locator统一资源定位符 src:Source资源 href:Hypertext Reference超文本引用

  4. 第二周个人作业WordCount

    1.Github地址 https://github.com/JingzheWu/WordCount 2.PSP表格 PSP2.1 PSP阶段 预估耗时 (分钟) 实际耗时 (分钟) Planning ...

  5. 配置文件错误导致jenkins无法启动 org.xmlpull.v1.XmlPullParserException: only 1.0 is supported as <?xml version not '1.1' (position: START_DOCUMENT seen <?xml version=\'1.1\'... @1:19)

    org.xmlpull.v1.XmlPullParserException: only 1.0 is supported as <?xml version not '1.1' (position ...

  6. CRM客户关系管理系统(一)

    第一章.CRM介绍和开发流程 1.1.CRM简介 客户关系管理(CRM) 客户关系管理(customer relationship management)的定义是:企业为提高核心竞争力,利用相应的信息 ...

  7. 0. 迷之 -> 和 .

    0. 迷之 -> 和 . 箭头(->):左边必须为指针: 点号(.):左边必须为实体. e.g.1 class class A{ public: play(); }; int main() ...

  8. async/await 的一些知识

    博文 Don't Block on Async Code What is the purpose of "return await" in C#? Any difference b ...

  9. page1

    1.1 常用的客户端技术:HTML. CSS. 客户端脚本技术 1.2 常用的服务器端技术:CGI .ASP .PHP (一种开发动态网页技术).ASP.NET(是一种建立动态web应用程序的技术,是 ...

  10. C++ substr

    函数文档:http://www.cplusplus.com/reference/string/string/substr/ /* substr(size_t pos = 0,size_t len = ...