通用Adapter设计,SparseArray+泛型+回调的使用
看到题目,我相信聪明的各位已经有一定想法了。 
一个Adapter,最简单的优化就是使用泛型,他可以省去非常多的代码,不过在此之上,我们还可以继续优化,优化他的好基友是:ViewHolder。 
在过去,我们通常使用一个内部类来写ViewHolder,换一种思路,我们用集合来设计ViewHolder,集合的泛型指定为View,这样ViewHolder就变成通用的了。 
原理知道了,后面只剩下代码逻辑问题了。 
(注:特别复杂的Listview或者RecycleView不适用,用集合替换ViewHolder,因为算法难度增加了,页面加载效率相对降低了,可能会出现页面抖动的情况)
源码:
使用情况:
public class ListRecycle extends AppCompatActivity {
    private RecyclerView recyclerView;
    private List<String> mDatas;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_list_recycle);
        recyclerView = (RecyclerView) findViewById(R.id.list_recycle_rv);
        initData();
        LinearLayoutManager layoutManager = new LinearLayoutManager(ListRecycle.this);
        recyclerView.setLayoutManager(layoutManager);
        layoutManager.setOrientation(OrientationHelper.VERTICAL);
        //使用情况就跟写按钮点击事件一样
        //指定泛型:String
        //参数:上下文,
        //     Item的布局Id,
        //     List(泛型和Adapter相同:String)
        recyclerView.setAdapter(new MyRecycleAdapter<String>(ListRecycle.this,
                R.layout.activity_list_recycle_item, mDatas) {
            @Override
            void bindView(MyViewHolder holder, String obj) {
                holder.setText(R.id.list_recycle_item_txt, obj);
            }
        });
        recyclerView.setItemAnimator(new DefaultItemAnimator());
    }
    private void initData() {
        mDatas = new ArrayList<String>();
        for (int i = 0; i < 40; i++) {
            mDatas.add("item" + i);
        }
    }
}实现类(以RecycleView的Adapter为例):
**
 * Created by ChenSS on 2016/9/21.
 */
public abstract class MyRecycleAdapter<T> extends RecyclerView.Adapter<MyRecycleAdapter.MyViewHolder> {
    //个人喜欢List
    private List<T> mData;
    private LayoutInflater mLayoutInflater;
    //Item的布局Id
    private int mLayoutRes;
    public MyRecycleAdapter(Context context, int mLayoutRes, List<T> mData) {
        this.mData = mData;
        this.mLayoutRes = mLayoutRes;
        mLayoutInflater = LayoutInflater.from(context);
    }
    @Override
    public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view = mLayoutInflater.inflate(mLayoutRes, null, false);
        return new MyViewHolder(view);
    }
    @Override
    public void onBindViewHolder(MyViewHolder holder, int position) {
        //调用我们自己的回调方法
        this.bindView(holder, mData.get(position));
    }
    //这个就是要回调的方法,其实也可以考虑回调onBindViewHolder的,但是自己写更灵活一些,参数可以自己指定,还可以考虑加别的
    abstract void bindView(MyRecycleAdapter.MyViewHolder holder, T obj);
    @Override
    public int getItemCount() {
        return mData != null ? mData.size() : 0;
    }
    public static class MyViewHolder extends RecyclerView.ViewHolder {
        //另一个关键点,集合,这个集合跟Map类似,效率比Map高
        private SparseArray<View> mViews;
        //RecycleView的一个item
        private View item;
        private static MyViewHolder sHolder = null;
        public MyViewHolder(View itemView) {
            super(itemView);
            item = itemView;
            mViews = new SparseArray<>();
        }
        /**
         * 最后一个关键点,封装findViewById,使用我们自己的
         *
         * @param id
         * @param <T>
         * @return
         */
        @SuppressWarnings("unchecked")
        public <T extends View> T findView(int id) {
            T t = (T) mViews.get(id);
            if (t == null) {
                t = (T) item.findViewById(id);
                mViews.put(id, t);
            }
            return t;
        }
        /**
         * 直接返回当前item,比如说:给Item添加点击事件,就不要用其它接口回调什么的了,已经用了其它回调,再用就太乱了
         */
        public View getItemView() {
            return item;
        }
        /**
         * 设置文字
         */
        public MyViewHolder setText(int id, CharSequence text) {
            View view = findView(id);
            if (view instanceof TextView) {
                ((TextView) view).setText(text);
            }
            return this;
        }
        /**
         * 设置点击监听
         */
        public MyViewHolder setOnClickListener(int id, View.OnClickListener listener) {
            findView(id).setOnClickListener(listener);
            return this;
        }
    }
}通用Adapter设计,SparseArray+泛型+回调的使用的更多相关文章
- 为RecyclerView打造通用Adapter
		##RecycleView简单介绍 RecyclerView控件和ListView的原理有非常多相似的地方,都是维护少量的View来进行显示大量的数据.只是RecyclerView控件比ListVie ... 
- 为RecyclerView打造通用Adapter 让RecyclerView更加好用
		原文出处: 张鸿洋 (Granker,@鸿洋_ ) 一.概述 记得好久以前针对ListView类控件写过一篇打造万能的ListView GridView 适配器,如今RecyclerView异军突起, ... 
- Android中适用于ListView、GridView等组件的通用Adapter
		今天随便逛逛CSDN,看到主页上推荐了一篇文章Android 高速开发系列 打造万能的ListView GridView 适配器,刚好这两天写项目自己也封装了相似的CommonAdapter,曾经也在 ... 
- Cocos Creator 通用框架设计 —— 资源管理优化
		接着<Cocos Creator 通用框架设计 -- 资源管理>聊聊资源管理框架后续的一些优化: 通过论坛和github的issue,收到了很多优化或bug的反馈,基本上抽空全部处理了,大 ... 
- 多租户通用权限设计(基于casbin)
		多租户通用权限设计(基于 casbin) 所谓权限控制, 概念并不复杂, 就是确认某个操作是否能做, 本质上仅仅就是个bool判断. 权限几乎是每个系统必不可少的功能, 和具体业务结合之后, 在系统中 ... 
- Android通用框架设计与完整电商APP开发系列文章
		作者|傅猿猿 责编|Javen205 有福利 有福利 有福利 鸣谢 感谢@傅猿猿 邀请写此系列文章 Android通用框架设计与完整电商APP开发 课程介绍 [导学视频] [课程详细介绍] 以下是部分 ... 
- Android简单开发之   通用Adapter ViewHolder
		我们寻常使用Adapter的方式 public class BusbaseSearchApadter extends SimpleBaseApadter { private List<Busba ... 
- Cocos Creator 通用框架设计 —— 网络
		在Creator中发起一个http请求是比较简单的,但很多游戏希望能够和服务器之间保持长连接,以便服务端能够主动向客户端推送消息,而非总是由客户端发起请求,对于实时性要求较高的游戏更是如此.这里我们会 ... 
- ASP.NET Aries 3.0发布(附带通用API设计及基本教程介绍)
		主要更新: 1:升级处理机制(js请求由同步变更为异步) 2:优化前端JS:包括API和配置方式. 3:增加InputDialog功能. 4:增远远程验证功能. 5:优化权限安全机制. 6:增加一次请 ... 
随机推荐
- mysql分表场景分析与简单分表操作
			为什么要分表 首先要知道什么情况下,才需要分表个人觉得单表记录条数达到百万到千万级别时就要使用分表了,分表的目的就在于此,减小数据库的负担,缩短查询时间. 表分割有两种方式: 1水平分割:根据一列或多 ... 
- Django(二)
			QuerySet与惰性机制: 所谓惰性机制:Publisher.objects.all()或者所谓惰性机制:Publisher.objects.all()或者.filter()等都只是返回了一个Que ... 
- 正六边形网格化(Hexagonal Grids)原理与实现
			在路径规划.游戏设计栅格法应用中,正六边形网格不如矩形网格直接和常见,但是正六边形具有自身的应用特点,更适用于一些特殊场景中,比如旷阔的海洋.区域或者太空.本文主要讲述如何对正六边形进行几何学分析.网 ... 
- 为Android设备添加A2SD支持
			相信很多用Android设备的用户都有这个问题,内部存储太小导致应用只能装那么几个,虽然rom也有提供移动到sd卡的选项,但是仅仅是移动程序文件到sd卡,并不能解决多少问题,多装几个还是会 ... 
- LINUX 笔记-ps命令
			使用该命令能确定有哪些进程正在运行和运行的状态.进程是否结束.进程有没有僵死.哪些进程占用了过多的资源等等 USER PID %CPU %MEM VSZ RSS TTY STAT START TIME ... 
- 基于Hadoop(M/R)的MySQL到Oracle海量数据切割
			# 背景介绍 大数据时代,海量数据的迁移会很普遍地出现在各个应用场景,本文主要讨论利用Sqoop的分布式能力从关系型数据库MySQL到Oracle的海量数据迁移和切割. # 所需环境 1 JDK+Ec ... 
- JqueryMobile基础之创建页面
			首先简答介绍一下JQueryMobile吧,我觉得用一句话来讲就是可以 "写更少的代码,做更多的事情" : 它可以通过一个灵活及简单的方式来布局网页,且兼容所有移动设备.这也是我自 ... 
- LeetCode 563. Binary Tree Tilt (二叉树的倾斜度)
			Given a binary tree, return the tilt of the whole tree. The tilt of a tree node is defined as the ab ... 
- centos 安装giblab
			本文章转载自:http://www.cnblogs.com/fanjingfeng/p/6665597.html 一, 服务器快速搭建gitlab方法 可以参考gitlab中文社区 的教程 cento ... 
- 有两组随机生成的(0~99999)Int32数据A和B,将A按顺序判断在B中是否存在并记录在Boolean型的C中
			http://www.cnblogs.com/asxinyu/p/4504487.html 
