实现注入view,简单案例剖析butterknife原理
来源:互联网 发布:mac怎么卸载百度云盘 编辑:程序博客网 时间:2024/04/29 07:52
ButterKnife注入框架我相信大家都用过至少听过吧,它的出现简直是android开发人员的一大福利,彻底解放了无止境的findViewById,而是通过优雅的注解来实现view的赋值,如果你真没听过那我在这里只能贴上一张github的截图,自己好好反思吧~
butterKnife地址
1w5的star你还有什么不学的理由!!!
好的,今天我们不说butterfnife怎么用,而是仿照框架中的实现原理,用最简单的例子自己来实现view的注入!
1、编写自定义注解类
既然是注入的形式对view赋值,那么当然少不了注解,我们最常用的莫过于setContentView和findViewById,我们先来定义这两个注解(注释中顺便帮同学们补一些注解的知识):
setContentView
/** * @Target描述注解的使用范围 * 1.CONSTRUCTOR:用于描述构造器 2.FIELD:用于描述域 3.LOCAL_VARIABLE:用于描述局部变量 4.METHOD:用于描述方法 5.PACKAGE:用于描述包 6.PARAMETER:用于描述参数 7.TYPE:用于描述类、接口(包括注解类型) 或enum声明 */@Target(ElementType.TYPE)/** * @Retention 该Annotation被保留的时间长短 * 1.SOURCE:在源文件中有效(即源文件保留) 2.CLASS:在class文件中有效(即class保留) 3.RUNTIME:在运行时有效(即运行时保留) */@Retention(RetentionPolicy.CLASS)public @interface SetContent { int value() default -1;}
findViewById
@Target(ElementType.FIELD)@Retention(RetentionPolicy.CLASS)public @interface BindView { int value();}
注解定义好之后,我们的目标是在activity中这样使用对不对
@SetContent(R.layout.activity_main)public class MainActivity extends AppCompatActivity { @BindView(R.id.tv_text) private TextView textView;}
这是我们需要一个解析器。
2、编写注解解析器,为这些view赋值
/** * Created by admin on 2017/4/2. * 注入解析器 * 单例 */public class MyAnnotationInject { private static MyAnnotationInject INSTANCE; private List<Object> mInjectObjs = new ArrayList<Object>(); public static MyAnnotationInject init() { if (INSTANCE == null) { INSTANCE = new MyAnnotationInject(); } return INSTANCE; } /** * 注册需要注入的类对象 * @param injectObj */ public void regist(@NonNull Object injectObj) { if(mInjectObjs.contains(injectObj)){ return; } if (injectObj instanceof Activity) { Activity activity = (Activity) injectObj; //拿到注入的class对象 Class<Activity> clz = (Class<Activity>) activity.getClass(); try { injectContentView(activity, clz); injectView(activity, clz); } catch (IllegalAccessException e) { e.printStackTrace(); } } mInjectObjs.add(injectObj); } /** * 注入view */ private void injectView(Activity activity, Class<Activity> clz) throws IllegalAccessException { //获得所有的属性,包括public、protected、private Field[] fields = clz.getDeclaredFields(); for (Field field : fields) { //遍历所有属性,找到标有Bindview注解的属性 if (field.isAnnotationPresent(BindView.class)) { //拿到BindView注解的值 BindView annotation = field.getAnnotation(BindView.class); int viewId = annotation.value(); //如果是私有属性,修改属性赋值之前必须加可修改权限 field.setAccessible(true); //给属性重新赋值,参数1:要修改的属性的对象 , 参数2 : 新值 field.set(activity, activity.findViewById(viewId)); } } } /** * 注入activity布局 */ private void injectContentView(Activity activity, Class<Activity> clz) { if (clz.isAnnotationPresent(SetContent.class)) { //拿到SetContent注解的值 SetContent annotation = clz.getAnnotation(SetContent.class); int resId = annotation.value(); if (resId != -1) { activity.setContentView(resId); } } } /** * 注销需要注入的类对象 * @param injectObj */ public void unRegist(Object injectObj) { if (mInjectObjs.contains(injectObj)) mInjectObjs.remove(injectObj); }}
3、Activity中使用我们的注解来代替findViewById
@SetContent(R.layout.activity_main)public class MainActivity extends AppCompatActivity { @BindView(R.id.tv_text) private TextView textView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); MyAnnotationInject.init().regist(this); textView.setText("通过注解注入view成功!"); } @Override protected void onDestroy() { super.onDestroy(); MyAnnotationInject.init().unRegist(this); }}
我们看一下效果:
当然我这只是butterknife中冰山一角,如果想要具体学习整个框架可以去学习butterknife的源码~
butterKnife地址,点我
0 0
- 实现注入view,简单案例剖析butterknife原理
- View注入框架:Butterknife简单使用
- ButterKnife--View注入框架
- ButterKnife--View注入框架
- ButterKnife--View注入框架
- ButterKnife--View注入框架
- ButterKnife--View注入框架
- ButterKnife--View注入框架
- ButterKnife--View注入框架
- ButterKnife--View注入框架
- ButterKnife--View注入框架
- ButterKnife--View注入框架
- ButterKnife--View注入框架
- ButterKnife--View注入框架
- ButterKnife--View注入框架
- ButterKnife--View注入框架
- ButterKnife--View注入框架
- ButterKnife--View注入框架
- SPPnet,Fast R-CNN和Faster R-CNN总结
- 一般神经元模型
- Info.plist配置文件(一些主要的属性配置)
- 数据库连接池+C3P0数据源
- CMake创建VTK程序
- 实现注入view,简单案例剖析butterknife原理
- C++小知识更新
- Linux ipcs命令与ipcrm命令的用法详解
- accelerated c++ 读书笔记--第十二章
- 1002. A+B for Polynomials (25)
- JavaScript之function类型(引用类型)
- 【Java 学习】之 getResourceAsStream
- HTML和CSS知识点总结
- Selenium Qzone登陆