通用Adapter设计,SparseArray+泛型+回调的使用

来源:互联网 发布:淘宝信誉刷到皇冠 编辑:程序博客网 时间:2024/06/06 03:58

看到题目,我相信聪明的各位已经有一定想法了。
一个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;        }    }}
0 0
原创粉丝点击