关闭

打造Android集合控件数据绑定(支持添加监听,支持AbsListView与RecycleView,支持异步加载等)(三)具体实现

标签: Android控件架构与设计orm框架
591人阅读 评论(1) 收藏 举报
分类:
在上面一篇中我们已经获得了所有必要的数据,下面就是在抽象好的onBinder回掉中调用这些method。

1.首先补一下上一篇的坑,Pojo类的解析过程如下

public void bind(AbsListView view,RecyclerView recyclerView,List<?> list,Class clazzType,Object ltnImpl){
        if (list == null)
            return;
        Class clazz = null;
        if (list.size() != 0)
            clazz = list.get(0).getClass();
        else
            clazz = clazzType;
        ListDataSrc listDataSrc = (ListDataSrc) clazz.getAnnotation(ListDataSrc.class);
        if (listDataSrc == null)
            return;
        List<ClassMemberPackage> mems = null;
        try {
            mems = ClassMemberParase.GetFileds(list.get(0));
        } catch (Exception e) {
            e.printStackTrace();
        }
        if (mems == null||mems.size()==0)
            return;
        final BinderPackage binderPackage = new BinderPackage();
        binderPackage.setList(list);
        for (ClassMemberPackage mem : mems){
            Annotation[] annotations = mem.getAnnotations();
            for (Annotation anno : annotations){
                ListBinderBase annobase = anno.annotationType()
                        .getAnnotation(ListBinderBase.class);
                ListBinderLtnBase ltnannobase = anno.annotationType()
                        .getAnnotation(ListBinderLtnBase.class);
                if (annobase!=null){
                    Method method = null;
                    try {
                        method = annobase.viewType().getDeclaredMethod(annobase.methodName(),annobase.dataType());
                    } catch (NoSuchMethodException e) {
                        e.printStackTrace();
                    }
                    if (method != null) {
                        BinderPackage.BinderTarget target =
                                binderPackage.new BinderTarget(annobase.viewType(), mem.getField(), method);

                        for (int item : getItems(anno))
                            binderPackage.getBindlist().put(item, target);
                    }
                }
                if (ltnannobase!=null){
                    Method method = null;
                    try {
                        method = ltnannobase.viewType().getDeclaredMethod(ltnannobase.listenerSetter(),ltnannobase.listenerType());
                    } catch (NoSuchMethodException e) {
                        e.printStackTrace();
                    }
                    if (method==null)
                        continue;
                    Object ltn = ltnImpl;
                    BinderPackage.BinderTarget target =
                            binderPackage.new BinderTarget(ltn,method,ltnannobase.listenerType());
                    for (int item:getItems(anno)){
                        if (binderPackage.getBindlist().get(item)==null){
                            binderPackage.getBindlist().put(item,target);
                        }else {
                            BinderPackage.BinderTarget tar = binderPackage.getBindlist().get(item);
                            tar.setLtnImpl(ltn);
                            tar.setLtnMethod(method);
                            tar.setLtnType(ltnannobase.listenerType());
                        }
                    }
                }
            }
        }
ClassMemberParse是我实现的用于解析对象成员变量的工具类,集成在我的框架中,后期可以将所有反射方法集成在里面,以便于添加缓存,提高框架解析速度。基本过程就是解析注解里的几个参数,加上一些判断,比较重要的是如果客户不想使用简单的ORM映射,可以自己实现onBinder回掉,这样就没有必要解析pojo类了。

2.onBinder的具体细节,这里参考了鸿翔老师的通用ViewHolder抽象出通用的onBinder回掉接口,并在此方法里使用前面解析的数据。
public void setHolder(IViewHolder holder, int position){
        for (int i = 0;i < bindlist.size();i++){
            int key = bindlist.keyAt(i);
            BinderTarget bt = bindlist.get(key);
            View view = holder.getView(key);
            Field field = bt.getField();
            Object value = null;
            if (field != null) {
                try {
                    value = field.get(list.get(position));
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                }
                if (value == null)
                    return;
            }
            Method method = bt.getMethod();
            Method ltnmethod = bt.getLtnMethod();
            Object ltnImpl = bt.getLtnImpl();
            try {
                if (method != null)
                    method.invoke(view,value);
                if (ltnmethod != null) {
                    ltnmethod.invoke(view, ltnImpl);
                    view.setTag(position);
                }
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            } catch (InvocationTargetException e) {
                e.printStackTrace();
            }
        }
    }

    public void setHolder(ViewHolder holder, int position){
        for (int i = 0;i < bindlist.size();i++){
            int key = bindlist.keyAt(i);
            BinderTarget bt = bindlist.get(key);
            View view = holder.getView(key);
            Field field = bt.getField();
            Object value = null;
            if (field != null) {
                try {
                    value = field.get(list.get(position));
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                }
                if (value == null)
                    return;
            }
            Method method = bt.getMethod();
            Method ltnmethod = bt.getLtnMethod();
            Object ltnImpl = bt.getLtnImpl();
            try {
                if (method != null)
                    method.invoke(view,value);
                if (ltnmethod != null) {
                    ltnmethod.invoke(view, ltnImpl);
                    view.setTag(position);
                }
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            } catch (InvocationTargetException e) {
                e.printStackTrace();
            }
        }
    }
两个setBinder分别对应AbsListView和RecycleView。总体来说代码还不怎么健壮,但是基本过程都表述的差不多了

最后是对外调用的接口,链式调用比较美观。
public class ExtCall{
        private AbsListView listView;
        private RecyclerView recyclerView;
        private Class clazz;
        private IAdapterCallBack callBack;
        private IRcAdapterCallBack rcCallBack;
        private Object ltnImpl;
        public ExtCall(AbsListView listView) {
            this.listView = listView;
        }

        public ExtCall(RecyclerView recyclerView) {
            this.recyclerView = recyclerView;
        }
        public ExtCall setClass(Class clazz){
            this.clazz = clazz;
            return this;
        }
        public ExtCall setCallBack(IAdapterCallBack callBack){
            this.callBack = callBack;
            return this;
        }

        public ExtCall setCallBack(IRcAdapterCallBack callBack){
            this.rcCallBack = callBack;
            return this;
        }

        public ExtCall setLtnImpl(Object ltnImpl) {
            this.ltnImpl = ltnImpl;
            return this;
        }

        public void bind(List<?> list){

            if (listView!=null){
                if (callBack == null)
                    getInstance().bind(listView,recyclerView,list,clazz,ltnImpl);
                else
                    getInstance().bind(listView,list,callBack,clazz);
            }

            if (recyclerView!=null){
                if (rcCallBack == null)
                    getInstance().bind(listView,recyclerView,list,clazz,ltnImpl);
                else
                    getInstance().bind(recyclerView,list,rcCallBack,clazz);
            }


        }



1
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:71207次
    • 积分:1204
    • 等级:
    • 排名:千里之外
    • 原创:44篇
    • 转载:1篇
    • 译文:0篇
    • 评论:33条
    博客专栏
    文章分类
    最新评论