文档章节

RecyclerView的通用适配器,和滚动时不加载图片的封装

爱看博客
 爱看博客
发布于 2015/10/22 10:06
字数 1064
阅读 46
收藏 0

很早之前写过一篇讲ListView的万能适配器的方案通用Adapter与ListView滚动时不加载图片的封装,可以让你在写ListView的Adapter时只关注对控件设置内容,而不需要再去考虑ViewHolder、控件初始化、以及实现BaseAdapter的其他三个必须实现的函数。
对于RecyclerView我们需要使用RecyclerAdapter,使用方式与ListViewAdapter类似,具体代码大家可以在网上搜索,这里就只教大家使用封装后的简洁RecyclerAdapter了。

核心代码

首先我们来看一部分核心代码:

        public abstract class BaseRecyclerAdapter<T> extends RecyclerView.Adapter<RecyclerHolder> {

            public BaseRecyclerAdapter(RecyclerView v, Collection<T> datas, int itemLayoutId) {
              //...
            }

            /** * Recycler适配器填充方法 * * @param holder viewholder * @param item javabean * @param isScrolling RecyclerView是否正在滚动 */
            public abstract void convert(RecyclerHolder holder, T item, int position, boolean isScrolling);

            @Override
            public RecyclerHolder onCreateViewHolder(ViewGroup parent, int viewType) {
                LayoutInflater inflater = LayoutInflater.from(cxt);
                View root = inflater.inflate(mItemLayoutId, parent, false);
                return new RecyclerHolder(root);
            }

            @Override
            public void onBindViewHolder(RecyclerHolder holder, int position) {
                convert(holder, realDatas.get(position), position, isScrolling);
                holder.itemView.setOnClickListener(getOnClickListener(position));
            }
        }

以及RecyclerHolder的代码

        public class RecyclerHolder extends RecyclerView.ViewHolder {
            private final SparseArray<View> mViews;

            public RecyclerHolder(View itemView) {
                super(itemView);
                //一般不会超过8个吧
                this.mViews = new SparseArray<View>(8);
            }

            /** * 通过控件的Id获取对于的控件,如果没有则加入views */
            public <T extends View> T getView(int viewId) {
                View view = mViews.get(viewId);
                if (view == null) {
                    view = itemView.findViewById(viewId);
                    mViews.put(viewId, view);
                }
                return (T) view;
            }

            /** * 为TextView设置字符串 */
            public RecyclerHolder setText(int viewId, String text) {
                TextView view = getView(viewId);
                view.setText(text);
                return this;
            }

            /** * 为ImageView设置图片 */
            public RecyclerHolder setImageByUrl(KJBitmap bitmap, int viewId, String url) {
                bitmap.display(getView(viewId), url);
                return this;
            }
        }

实现原理

其实实现原理和我们之前讲过的ListView通用适配器的实现原理是一致的。Google以及在RecyclerAdapter中规范了Holder的应用,加入了onCreateViewHolder()和onBindViewHolder()方法分别来实现ViewHolder的创建和对Holder中的控件设置内容。
但是适配器写多了以后我们就会发现,其实这两个函数中写的内容也是重复的,于是就有了RecyclerHolder这个我们自己封装的Holder。
与平时我们自己实现的ViewHolder最大的不同在于,我们以前定义ViewHolder都是一个item里面要用哪个控件就定义哪个控件,而为了通用,我们抽出它们共同的部分————都是View。
但是我们还不知道我们的item中究竟会有多少个控件,所以这里我们再定义一个集合类,当然它也可以是一个Map(不能是List,因为我们还需要读取这个View呢,如果是List,就不知道哪个View保存在List的哪个index了,而用map可以通过View的id来作为key读取),这里我们依旧使用推荐的SparseArray,原因我们之前的通用ListView适配器中已经讲过了,这里就不再多说了,只需要把它看成是一个性能更好的Map就行了。

完整代码

最后,还有一个细节大家可以在完整代码中看到,就是我加入了滚动监听与item点击事件,这样就可以很方便的在基类中实现RecyclerView滚动的时候不加载图片,以及Google没有提供的RecyclerView的item点击事件了。

一点补充

有关滚动时不加载图片,之前有人提起了说我没有提到,这里就顺带讲一下实现原理:
其实就是在我们我适配器中声明一个全局的boolean变量用来保存此刻是否在滚动,然后通过给ListView或RecyclerView设置滚动监听,然后在滚动监听器的onScrollStateChanged()方法中给boolean值赋值,看是否在滚动。
这样在我们使用这个适配器的时候,就可以根据滚动状态的不同来判断:比如正在滚动的时候就只显示内存缓存的图片,如果内存缓存中没有就显示一张默认图片;而如果没有在滚动就采用正常的图片加载方案去加载网络或者缓存中的图片。

版权声明:本文原创,转载请注明来自 http://kymjs.com/

本文转载自:http://blog.csdn.net/kymjs/article/details/49068675

共有 人打赏支持
爱看博客
粉丝 5
博文 103
码字总数 23887
作品 0
深圳
私信 提问
RecyclerView的通用适配器,和滚动时不加载图片的封装

很早之前写过一篇讲ListView的万能适配器的方案通用Adapter与ListView滚动时不加载图片的封装,可以让你在写ListView的Adapter时只关注对控件设置内容,而不需要再去考虑ViewHolder、控件初始...

kymjs张涛
2015/10/11
1K
2
说说 Android 的 Material Design 设计(四)——卡片式布局

我们使用 CardView 与 RecyclerView 来·实现一个各种猫的卡片式展示列表吧O(∩_∩)O~ 1 CardView 控件 1.1 引入依赖库 打开 app/build.gradle,添加依赖库: 最后一行引入的 Glide,它是一个...

deniro
09/22
0
0
APP实现与原理

实现 不需要任何权限获得Android设备的唯一ID RecyclerView的通用适配器,和滚动时不加载图片的封装 完美的解决如何让AsyncTask终止操作 webview rexsee sdcard 缓存文件可以放在哪里?它们各...

addcn
2015/12/16
60
0
【Android】RecyclerView下拉刷新与加载更多

知道自己不能做什么远比知道自己能做什么重要。 RecyclerView是Android L版本中新添加的控件,它的灵活性、可替代性、回收机制等比listview更好。可能对于一些使用过RecyclerView的开发者会说...

zrunker
2017/10/26
0
0
Android简易实战教程--第四十六话《RecyclerView竖向和横向滚动》

Android5.X后,引入了RecyclerView,这个控件使用起来非常的方便,不但可以完成listView的效果,而且还可以实现ListView无法实现的效果。当然,在新能方便也做了大大的提高。本篇 第四十六话...

qq_32059827
2016/12/07
0
0

没有更多内容

加载失败,请刷新页面

加载更多

如何在Angular中使用better-scroll插件

由于需要在一个固定的的高度做无限滚动,本来css的overflow-y也可以完成的,奈何安卓不是很流畅,还很生硬,就是用了第三方库better-scroll,配合angular的ng-content。angular的ng-content和...

前端攻城老湿
2分钟前
0
0
Js中apply和Math.max()函数的问题及区别

这篇文章主要介绍了js中apply和Math.max()函数的问题,本文给大家带来两种答案,每一种答案给大家介绍的非常详细,在文章底部给大家提到了js中Math.max.apply和Math.max的区别,写的十分的全...

前端攻城小牛
2分钟前
0
0
解决 SpringBoot 不继承父starter-parent打包不包含依赖的问题

由于项目需要继承自己平台的父 parent , 有的模块是纯 api ,不能有任何依赖, 所以父 parent 不能直接引入 springboot, 单独给非 boot 项目排除依赖的话又特别的麻烦, 且不好把控。 记得刚接触...

stys35
4分钟前
0
0
vuex进阶知识点巩固

我们先回忆一下上一篇的代码 computed:{ getName(){ return this.$store.state.name }} 这里假设现在逻辑有变,我们最终期望得到的数据(getName),是基于 this.$store.state.na...

嫣然丫丫丫
19分钟前
1
0
Python出现安全策略问题的解决方法

Python运行期间出现如下错误 import: attempt to perform an operation not allowed by the security policy `PS' @ error/constitute.c/IsCoderAuthorized/408. 解决方法:在脚本的开头添加......

大糊涂
27分钟前
1
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部