安卓控件android开发技巧Android iOS开发知识库

我是如何搭建Android快速开发框架的之UI篇(中)

2016-12-13  本文已影响2319人  droidlover

接着上篇,这里想分享ListAdapter、RecyclerView的封装。众所周知,ListAdapter以及RecyclerView都是列表控件,Google更推荐大家使用RecyclerView。关于RecyclerView的基本使用,不在本篇的讨论范围内。

ListAdapter

ListAdapter作为ListView的数据适配器,为ListView提供数据源。在我们的频繁使用中,发现:对Adapter的编写主要集中在几部分:

而在getView()方法中,我们通常会做这么几件事:

转化成代码:

 if (convertView == null) {
       convertView = View.inflate(context, getLayoutId(), null);
       holder = new ViewHolder(convertView);
       convertView.setTag(holder);
   } else {
       holder =  convertView.getTag();
   }
   
   bindItem();      //绑定数据
   setEvent();      //绑定事件
   
   return convertView;

由于Adapter可多个itemType,因此封装的时候缤纷两路,RecyclerAdapter的封装也是如此。

Step1 封装XListAdapter,作为所有Adapter的基类,子类可实现getView()方法

XListAdapter中主要实现了数据集的增删修改常用操作事件绑定接口 等功能。

+ addData()
+ setData()
+ clearData
+ addElement()
+ removeElement()
+ getColor()
+ getDrawable()
+ visible()
+ gone()
+ invisible()
...

Step2 封装SimpleListAdapter,实现单viewType的需求

核心如下:

 @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        H holder = null;
        T item = data.get(position);

        if (convertView == null) {
            convertView = View.inflate(context, getLayoutId(), null);
            holder = newViewHolder(convertView);

            convertView.setTag(holder);
        } else {
            holder = (H) convertView.getTag();
        }

        convert(holder, item, position);

        return convertView;
    }

子类则摆脱了这段魔鬼一样的代码,只需要实现这三个方法:

protected abstract H newViewHolder(View convertView); //创建viewHolder

protected abstract int getLayoutId();       //设置布局资源id

protected abstract void convert(H holder, T item, int position);    //数据绑定与事件绑定

Step3 事件绑定接口

为了方便事件的统一处理,我抽象了一个抽象类ListItemCallback

 public void onItemClick(int position, T model, int tag) {}         //单击

 public void onItemLongClick(int position, T model, int tag) {}     //长按

参数:

a. 为什么定义的是抽象类,而不是接口?

因为接口中的方法需要全部实现,而抽象类可以选择性的override,显然,我们通常只需要重写onItemClick方法

b. 如何使用呢?

holder.itemView.setOnClickListener(new View.OnClickListener() {
     @Override
     public void onClick(View v) {
         if (getCallback() != null) {
             getCallback().onItemClick(position, item, TAG_VIEW);
         }
     }
 });

c. 为什么我不选择很常见的SparseArray那种封装的CommonAdapter

因为我不喜欢那种编码style,建议将Adapter单独类

RecyclerView

RecyclerView的封装一般体现在:

鉴于此,我之前搞了个ARecyclerView,主要有这些特性:

由于其实现相对复杂,推荐大家可以去看看源码,app mudule中是完整的实例

XDroid中,我新增了SimpleRecAdapter,应对单itemType的需求。具体思想和ListAdapter很相似

public abstract class SimpleRecAdapter<T, F extends RecyclerView.ViewHolder> extends RecyclerAdapter<T, F> {

    public SimpleRecAdapter(Context context) {
        super(context);
    }

    @Override
    public F onCreateViewHolder(ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(parent.getContext()).inflate(getLayoutId(), parent, false);
        return newViewHolder(view);
    }

    public abstract F newViewHolder(View itemView);

    public abstract int getLayoutId();

}

T 是item的实体类,F是ViewHolder的实体类

下一篇会谈谈ContentLayout的实现过程。

XDroid项目是我在两年的开发中积累的一个Android快速开发框架,目前包含UI层、缓存、图片加载、日志、路由、Api请求、事件订阅、工具类等。下一步会进行mvp、rx全家桶、retrofit、权限适配等工作。欢迎大家提出宝贵意见,指正不足。

最后附上链接: https://github.com/limedroid/XDroid

上一篇下一篇

猜你喜欢

热点阅读