RecyclerView的使用心得记录

关于recyclerview分页功能的实现方法:
一、自定义RecyclerView
有人已经造好轮子里,泡网大神,XRecyclerView,Github链接

二、自定义OnScrollListener
我是参考csdn上的这篇博文,让RecyclerView支持加载更多(Endless RecyclerView)

使用方法很简单,如下

 mRecyclerView.addOnScrollListener(new OnRecyclerLoadMoreListener() {
            @Override
            public void onLoadMore() {
                        calculate();
                        loadListMore();
            }
        });

calculate()这个方法就是用来计算start和limit值的

 private int start = 0; // 当前页数
 private int limit = 5; // 为每页显示数据数目
 private int totalCount;// 列表总条数,在第一次加载列表数据接口时就应该拿到值了

 private void calculate() {
        int current = adapter.getItemCount();
        if (current + limit < totalCount) {
            start = current;
        } else {
            start = current;
            limit = totalCount - current;
        }
    }

loadListMore方法就是用来加载更多网络数据的,方法内容和初次进来加载列表数据的方法基本一致,只是把返回的数组放到一个新的集合list中去(比如listMore),然后再使用初次加载列表数据的listData的addAll方法把listMore全部加进去,list就由原来的5条变成了10条,同时去更新adapter,这样就实现了基本的上拉加载更多功能。
至于recyclerview的下拉刷新功能,只需要靠swiperefreshlayout的setOnRefreshListener方法就好了

————————————————–久违的分割线——————————————-

RecyclerView作为ListView和GridView的替代者,这几天花点时间学习了下,虽然已经出来好久了,但是我现在才开始了解它,真是愧疚愧疚,谨以此文来记录下学习过程中的心得体会。
国际惯例,先上一张要实现的效果图:

这里写图片描述

看起来比较简单,大概涉及到以下几个功能点:
1、RecyclerView的嵌套
2、配合SwipeRefreshLayout使用实现的下拉刷新、上拉加载更多(分页)效果
3、添加分隔线、添加item点击事件、通用ViewHolder及适配器
4、GridLayoutManager高度自适应以及相等的间隔:目前是根据list大小先固定三种高度
5、添加headerView,参考这里
6、侧滑功能(未添加)–> com.daimajia.swipelayout:library
7、拖拽排序功能(未添加)–> DragSortListViewLibrary

主要代码如下(RecyclerView滑动监听参考链接):

        mRecyclerView = (RecyclerView) findViewById(R.id.aboutUs_recycleView);
        swipeRefreshLayout = (SwipeRefreshLayout) findViewById(R.id.recycleview_swiperefresh);

        // RecycleView初始化配置
        LinearLayoutManager layoutManager = new LinearLayoutManager(this);
        layoutManager.setOrientation(LinearLayoutManager.VERTICAL);
        mRecyclerView.setLayoutManager(layoutManager);
        //设置Item增加、移除动画
        mRecyclerView.setItemAnimator(new DefaultItemAnimator());
        //添加分割线
        mRecyclerView.addItemDecoration(new DividerItemDecoration(
                TestRecyclerViewActivity.this, DividerItemDecoration.VERTICAL_LIST));
        mRecyclerView.setHasFixedSize(true);// 其实我还没完全明白这个设置的作用

        // 设置下拉刷新圆圈图标可变换的颜色,默认为黑色
        swipeRefreshLayout.setColorSchemeResources(R.color.blue,
                R.color.orange,
                R.color.red);

        // 下拉刷新
        swipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
            @Override
            public void onRefresh() {
                start = 0;
                limit = 5;
                loadData();
            }
        });

        // 上拉加载更多
        mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {

            boolean isSlidingToLast = false;

            @Override
            public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
                LinearLayoutManager manager = (LinearLayoutManager) mRecyclerView.getLayoutManager();
                if (newState == RecyclerView.SCROLL_STATE_IDLE) {
                    int lastVisibleItem = manager.findLastCompletelyVisibleItemPosition();
                    int totalCount = manager.getItemCount();
                    if (lastVisibleItem == (totalCount - 1) && isSlidingToLast) {
                        calculate();
                        loadListMore();
                    }
                }
            }

            @Override
            public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
                super.onScrolled(recyclerView, dx, dy);
                if (dy > 0) {
                    isSlidingToLast = true;
                } else {
                    isSlidingToLast = false;
                }
            }
        });

        loadData();

先绑定控件,初始化RecyclerView和SwipeRefreshLayout配置,然后添加下拉刷新和上拉加载更多的监听事件,最后加载默认数据

为了测试方便,加载数据都是写死的,如下:

    private void calculate() {
        int current = adapter.getItemCount();
        if (current + limit < totalCount) {
            start = current;
        } else {
            start = current;
            limit = totalCount - current;
        }
    }

    private void loadData() {
        // 加载数据
        mListData.clear();
        for (int i = start + limit - 1; i >= 0; i--) {
            RecycleBean recycleBean = new RecycleBean();
            recycleBean.setId(i);
            recycleBean.setName("name" + i);
            recycleBean.setContent("content" + i);
            List<RecycleImageBean> imageList = new ArrayList<>();
            for (int j = 0; j < i + 1; j++) {
                RecycleImageBean imageBean = new RecycleImageBean();
                imageBean.setId(j);
                imageBean.setImage(sampleUrl);
                imageList.add(imageBean);
            }
            recycleBean.setImageList(imageList);
            mListData.add(recycleBean);
        }

        // 创建Adapter,并指定数据集
        adapter = new MyRecyclerAdapter(TestRecyclerViewActivity.this, mListData);
        // 绑定Adapter到RecyclerView上
        mRecyclerView.setAdapter(adapter);
        // 停止刷新
        swipeRefreshLayout.setRefreshing(false);
        adapter.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                Toast.makeText(TestRecyclerViewActivity.this, "点击了item" + position, Toast.LENGTH_SHORT).show();
            }
        });

    }

    private void loadListMore() {
        mListDataMore.clear();
        for (int i = start; i < start + limit; i++) {
            RecycleBean recycleBean = new RecycleBean();
            recycleBean.setId(i);
            recycleBean.setName("更多name" + i);
            recycleBean.setContent("更多content" + i);
            List<RecycleImageBean> imageList = new ArrayList<>();
            for (int j = 0; j < i + 1; j++) {
                RecycleImageBean imageBean = new RecycleImageBean();
                imageBean.setId(j);
                imageBean.setImage(sampleUrl);
                imageList.add(imageBean);
            }
            recycleBean.setImageList(imageList);
            mListData.add(recycleBean);
        }

        mListData.addAll(mListDataMore);
        adapter.notifyDataSetChanged();
//        adapter.notifyItemInserted(); // 建议使用这种更新adapter方式,带position参数
        if(adapter.getItemCount() >=totalCount) {
           Toast.makeText(TestRecyclerViewActivity.this, "数据全部加载完毕", Toast.LENGTH_SHORT).show();
        }

    }

还有就是两个adapter的代码,继承自basereyclerviewadapter,不好意思忘了在哪边搜到的这些代码,以后找到出处在补上

    public class GridImageAdapter extends BaseRecyclerViewAdapter {

        public GridImageAdapter(Context context, List<?> list) {
            super(context, list);
        }

        @Override
        public int onCreateViewLayoutID(int viewType) {
            return R.layout.main_recycleview_image_item;
        }

        @Override
        public void onBindViewHolder(RecyclerHolder holder, int position) {
            RecycleImageBean item = (RecycleImageBean) list.get(position);
            ImageLoader.getInstance().displayImage(item.getImage(), holder.getImageView(R.id.recycleview_image_item_iv));
        }
    }

    public class MyRecyclerAdapter extends BaseRecyclerViewAdapter {


        public MyRecyclerAdapter(Context context, List<?> list) {
            super(context, list);
        }

        @Override
        public int onCreateViewLayoutID(int viewType) {
            return R.layout.main_recycleview_item;
        }

        @Override
        public void onBindViewHolder(RecyclerHolder holder, int position) {
            final RecycleBean item = (RecycleBean) list.get(position);
            RecyclerView gridRecyclerView = holder.getRecycleview(R.id.recycleview_item_recycleView);
            TextView contentTV = holder.getTextView(R.id.recycleview_item_content);
            TextView timeTV = holder.getTextView(R.id.recycleview_item_time);

            // RecyclerView初始化配置
            gridRecyclerView.setLayoutManager(new GridLayoutManager(TestRecyclerViewActivity.this, 3));
            // 设置Item增加、移除动画
            gridRecyclerView.setItemAnimator(new DefaultItemAnimator());

            // 代码中设置嵌套的recyclerview的高度
            int gHeight = 0;
            int gSize = item.getImageList().size();
            if (gSize == 1 || gSize == 2 || gSize == 3) {
                gHeight = (int) getResources().getDimension(R.dimen.width_45_160);
            } else if (gSize == 4 || gSize == 5 || gSize == 6) {
                gHeight = (int) getResources().getDimension(R.dimen.width_90_160);
            } else if (gSize == 7 || gSize == 8 || gSize == 9) {
                gHeight = (int) getResources().getDimension(R.dimen.width_135_160);
            }
            gridRecyclerView.getLayoutParams().height = gHeight;

            GridImageAdapter demoAdapter = new GridImageAdapter(TestRecyclerViewActivity.this, item.getImageList());
            gridRecyclerView.setAdapter(demoAdapter);

            demoAdapter.setOnItemClickListener(new AdapterView.OnItemClickListener() {
                @Override
                public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                    Log.i("TAG", "点击了" + item.getImageList().get(position).getImage());
                }
            });
            contentTV.setText(item.getContent());
            timeTV.setText(item.getName());

        }
    }

然后就是通用的ViewHolder

import android.support.v7.widget.RecyclerView;
import android.view.View;

/**
 * Date: 2016/1/26 14:17
 * Email: diyangxia@163.com
 * Author: diyangxia
 * Description: RecyclerView通用ViewHolder
 */
public class RVHolder extends RecyclerView.ViewHolder {

    private RecyclerHolder viewHolder;
    public RVHolder(View itemView) {
        super(itemView);
        viewHolder= RecyclerHolder.getViewHolder(itemView);
    }
    public RecyclerHolder getViewHolder() {
        return viewHolder;
    }
}

import android.support.v7.widget.RecyclerView;
import android.util.SparseArray;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;

public class RecyclerHolder {
    private SparseArray<View> viewHolder;
    private View view;

    public static RecyclerHolder getViewHolder(View view) {
        RecyclerHolder viewHolder = (RecyclerHolder) view.getTag();
        if (viewHolder == null) {
            viewHolder = new RecyclerHolder(view);
            view.setTag(viewHolder);
        }
        return viewHolder;
    }

    private RecyclerHolder(View view) {
        this.view = view;
        viewHolder = new SparseArray<View>();
        view.setTag(viewHolder);
    }

    public <T extends View> T get(int id) {
        View childView = viewHolder.get(id);
        if (childView == null) {
            childView = view.findViewById(id);
            viewHolder.put(id, childView);
        }
        return (T) childView;
    }

    public View getConvertView() {
        return view;
    }

    public TextView getTextView(int id) {
        return get(id);
    }

    public Button getButton(int id) {
        return get(id);
    }

    public ImageView getImageView(int id) {
        return get(id);
    }

    public void setTextView(int id, CharSequence charSequence) {
        getTextView(id).setText(charSequence);
    }

    public RecyclerView getRecycleview(int id) {
        return get(id);
    }
}

以及通用RecyclerView适配器:

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

import java.util.List;

/**
 * Date: 2016/1/26 14:08
 * Email: diyangxia@163.com
 * Author: diyangxia
 * Description: RecyclerView通用适配器
 */
public abstract class BaseRecyclerViewAdapter extends RecyclerView.Adapter<RVHolder> {
    public List<?> list;
    private Context context;

    public BaseRecyclerViewAdapter(Context context, List<?> list) {
        this.list = list;
        this.context = context;
    }

    @Override
    public RVHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(context).inflate(onCreateViewLayoutID(viewType), null);
        return new RVHolder(view);
    }

    public abstract int onCreateViewLayoutID(int viewType);

    @Override
    public void onViewRecycled(final RVHolder holder) {
        super.onViewRecycled(holder);
    }

    @Override
    public void onBindViewHolder(final RVHolder holder, final int position) {
        onBindViewHolder(holder.getViewHolder(), position);
        if (onItemClickListener != null) {
            holder.itemView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    onItemClickListener.onItemClick(null, v, holder.getPosition(), holder.getItemId());
                }
            });
        }
    }

    public abstract void onBindViewHolder(RecyclerHolder holder, int position);

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

    private AdapterView.OnItemClickListener onItemClickListener;

    public AdapterView.OnItemClickListener getOnItemClickListener() {
        return onItemClickListener;
    }

    /**
     * 添加Item点击事件
     */
    public void setOnItemClickListener(AdapterView.OnItemClickListener onItemClickListener) {
        this.onItemClickListener = onItemClickListener;
    }

布局文件和两个实体类就不贴了,以上代码系搜索引擎都拼西凑而来,毕竟有大牛造好了轮子干嘛不用。

修复Scrollview嵌套了RecyclerView无法全屏滑动的问题:重写LinearLayoutManager,详见链接1 链接2

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值