文档章节

[原]Android 插件 根据布局xml自动生成ViewHolder 技术分享(一)

l
 lingoes
发布于 2015/05/22 15:19
字数 776
阅读 488
收藏 49

码农小鸥, 在看某TT开源项目的Android实现, 发现到处分布的ViewHolder, 作为有代码洁癖的小码农, 小鸥觉得这个地方应该有很大的优化点.


基本的ViewHolder的样式

public class MyViewHorlder
{
    public TextView textView;
    public Button button;
}

ViewHolder的作用

1.保存各种View, 方便下次使用.

2.设计上抽出视图层次, 更便于MVC的实现. 


但是繁琐的是

1.ViewHolder的各种定义, 基本上一个Layout下的布局文件, 对应一个ViewHolder.

2.调用大量的findViewById函数对这个ViewHolder初始化.


这种繁琐没乐趣的事是码农最最痛恨的. 以作为一个纯粹的码农自居的小鸥表示这种工作模式不能忍.


那么怎么办呢?


既然一个layout文件可以对应一个ViewHolder, 何不写个eclipse插件来自动完成从layout.xml=>ViewHolder.java的转化呢?


说干就干.

首先, 设计我们大致需要的ViewHolder的模型

/**
 * @author zju_wjf
 *
 */
public interface IViewHolder {
    /**
     * 对应的R.layout中 id
     * @return
     */
    public int getId() ;
    
    /**
     * 自定义实现, 根据数据设置View的展示等
     * @param data
     */
    public void initByData(Bundle data);
    
    /**
     * 获得该ViewHolder的根View
     * @return
     */
    public View getRootView();
    
    /**为该ViewHolder设置根View
     * 
     * @param rootView
     */
    public void setRootView(View rootView);
}

一个ViewHolder 会有

1.一个根View

2.一个R.layout.id和它唯一对应

3.一个根据数据模型设置View的属性的同步方法.



实现了IViewHolder接口的抽象类 AbstractViewHolder

/**
 * @author zju_wjf
 */
public abstract class AbstractViewHolder implements IViewHolder {

    private View rootView;
    
    @Override
    public View getRootView(){
        return rootView;
    }

    @Override
    public void setRootView(View rootView){
        this.rootView = rootView;
    }
    
    @Override
    public void initByData(Bundle data) {
    }
}



下面是我们的主角出场啦, 最终生成的ViewHolder 应该是这个样子滴 - -

public class Tt_activity_preview_text extends AbstractViewHolder{

  	@ViewHolderInject(id = R.id.textView)
	public TextView textView;
	
	@ViewHolderInject(id = R.id.button)
	public Button button;
	
	public final int getId() {
		return R.layout.tt_activity_preview_text;
	}
}

等等, 这里怎么多出了@ViewHolderInject这家伙?

这个注解类是为了辅助自动为ViewHolder注入各种View而生成的.


于是我们应该有一个工具类来生成这个ViewHolder实例 以及自动注入这个ViewHolder内部的所有View.

/**
 * @author zju_wjf
 *
 */
public class ViewHolderUtils {
    
    public static <T extends IViewHolder> T create(final Class<T> _class, final Context context, final ViewGroup viewGroup) throws InstantiationException, IllegalAccessException {
        final T t = _class.newInstance();
        
        final View rootView = LayoutInflater.from(context).inflate(t.getId(), viewGroup);
        t.setRootView(rootView);
        
        injectViews(t);
        
        return t;
    }
    
    private static void injectViews(IViewHolder viewSet) throws IllegalArgumentException, IllegalAccessException {
        final Class<? extends IViewHolder> _class = viewSet.getClass();
        final View rootView = viewSet.getRootView();
        
        final Field [] fields = _class.getFields();
        for(Field field:fields) {
            final ViewHolderInject viewInject = field.getAnnotation(ViewHolderInject.class);
            if(viewInject != null) {
                //去除检查, 提高反射效率
                field.setAccessible(true);
                final View sub = rootView.findViewById(viewInject.id());
                field.set(viewSet, sub);
            }
        }
    }
}

有了它, 我们再也不用写讨厌的findViewById了.



大功告成, 我们基本上可以试一试了.

 try {
             Tt_activity_preview_text myTt_activity_preview_text = ViewHolderUtils.create(Tt_activity_preview_text.class, this, null);
             
             myTt_activity_preview_text.textView.setText("Hello ViewHolder.");
        } catch (InstantiationException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }



小鸥写的有些老太太的裹脚布, 又臭又长了. 那么如何编写这个自动生成的eclipse插件的工程就放在下一章吧.


项目git地址:https://github.com/zjuwjf/AutoViewHolder


© 著作权归作者所有

l
粉丝 2
博文 2
码字总数 1920
作品 0
杭州
私信 提问
打造你的开发神器——介绍Android Studio上的几个插件

这个月因为各种事情在忙,包括赶项目,回老家,还有准备旅游的事,所以应该写不了四篇博客了。今天介绍一下关于Android Studio 的几个好用的插件,都是我在用的,它们或能帮你节省时间,或者...

浩码农
2015/04/11
0
0
Android studio插件整理

Android studio 以下简称AS,*号表示插件的常用比例,越高常用性越高 AS打开设置的快捷键Ctrl + alt + S 在线安装:File-->settings-->Plugins-->Browse repositories-->然后再输入框输入But...

惟吾德馨_慧
2018/05/23
0
0
Kotlin Android Extensions使用指南

Kotlin Android Extensions是Kotlin团队开发的一个插件,目的是让我们在开发过程中更少的编写代码。目前包括了视图绑定的功能。 几种绑定视图方式对比 xml文件如下 第一种,传统方式绑定视图...

猴亮屏
2018/10/29
88
0
自定义Android的ListView布局和各Item的背景色

Android中的ListView是用得非常频繁的一种组件,同时ListView也是一种很强大的组件,你可以为每一行自定义布局,也可以修改各行的 背景色。自定义布局比较容易,自己实现一个layout的布局文件...

LiSteven
2013/03/28
5K
0
Kotlin Android Extensions

原文地址:https://proandroiddev.com/kotlin-android-extensions-the-definitive-guide-786d190b30e7 Kotlin Android Extensions是一个Kotlin插件,将会生成一些额外的代码然你跟可以访问布...

小菜鸟程序媛
2018/09/10
0
0

没有更多内容

加载失败,请刷新页面

加载更多

nginx学习笔记

中间件位于客户机/ 服务器的操作系统之上,管理计算机资源和网络通讯。 是连接两个独立应用程序或独立系统的软件。 web请求通过中间件可以直接调用操作系统,也可以经过中间件把请求分发到多...

码农实战
今天
5
0
Spring Security 实战干货:玩转自定义登录

1. 前言 前面的关于 Spring Security 相关的文章只是一个预热。为了接下来更好的实战,如果你错过了请从 Spring Security 实战系列 开始。安全访问的第一步就是认证(Authentication),认证...

码农小胖哥
今天
12
0
JAVA 实现雪花算法生成唯一订单号工具类

import lombok.SneakyThrows;import lombok.extern.slf4j.Slf4j;import java.util.Calendar;/** * Default distributed primary key generator. * * <p> * Use snowflake......

huangkejie
昨天
12
0
PhotoShop 色调:RGB/CMYK 颜色模式

一·、 RGB : 三原色:红绿蓝 1.通道:通道中的红绿蓝通道分别对应的是红绿蓝三种原色(RGB)的显示范围 1.差值模式能模拟三种原色叠加之后的效果 2.添加-颜色曲线:调整图像RGB颜色----R色增强...

东方墨天
昨天
11
1
将博客搬至CSDN

将博客搬至CSDN

算法与编程之美
昨天
13
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部