不诗意的女程序媛不是好厨师~
转载请注明出处,From李诗雨—https://blog.csdn.net/cjm2484836553/article/details/104539874
好的,下面就是见证奇迹的时刻啦:
成功啦!我成功啦,啊哈哈哈哈~
完成了布局注入,那我们下面继续控件注入吧~
3.控件注入上面我们的布局已经注入成功,并且可以正常显示了。
我们可以看到布局中有2个按钮,那如果我想把这两个按钮注入该怎么办呢?
即:我现在不想自己通过findViewById来注入按钮,而是想让我的【ioc女朋友】来帮我实现按钮的注入~
我们先来看一下我的预期想达到的效果:
那要达到这种效果我们该怎么实现呢?
有了布局注入的经验,相信对于 控件注入 大家还是会有大体的思路的:
我们还用之前的女朋友InjectUtils,还是在BaseActivity中进行注入。
那我们就要在InjectUtils里添加一个控件注入的方法injectView():
现在我们既然不想自己使用findViewById来获取控件,而是想用这种形式来注入控件:
那我们肯定还是要通过使用注解,并且在注解后面传入对应控件的id。
所以第①步,我们要自定义一个BindView注解:
//① 自定义一个BindView注解
@Target(ElementType.FIELD) //说明该注解是用在属性上的
@Retention(RetentionPolicy.RUNTIME)//该注解可以保留到程序运行的时候
public @interface BindView {
int value();
}
第②步,具体实现injectView()方法。
实现injectView()方法是重点,让我们来仔细分析一下思路:
首先,我们肯定还是要通过反射,所以要先拿到Activity对应的Class. 拿到了clazz后,我们还要拿到clazz上的所有属性字段(Fields)。▲▲▲ 然后我们就要循环遍历属性,看属性上是否有BindView注解。 如果属性上确实拿到了BindView注解,那我们就要继续拿到注解后面的viewId了。 再接着就是反射执行findViewById方法,得到对应的view. 最后要注意,对于私有属性,无论是对它进行读写,都要调用field.setAccessible(true)。▲private static void injectView(Object context) {
//获取clazz
Class clazz = context.getClass();
//获取clazz上的所有属性
Field[] fields = clazz.getDeclaredFields();
//循环遍历每一个属性
for (Field field : fields) {
//获取属性上的BindView注解
BindView bindView = field.getAnnotation(BindView.class);
if (bindView != null) {//如果该属性上找到了BindView注解
//拿到注解后面的viewId
int viewId = bindView.value();
//运行到这里,每个按钮的ID已经取到了
//下面就是反射执行findViewById方法
try {
Method method = clazz.getMethod("findViewById", int.class);
View view = (View) method.invoke(context, viewId);
//对 field 做相关操作
//注意:如果获取的字段是私有的,不管是读还是写,都要先 field.setAccessible(true);才可以。否则会报:IllegalAccessException。
field.setAccessible(true);
field.set(context, view);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
好的,现在我们控件注入的相关操作就完成了,那让我们来改个button的名称测试一下吧:
@MyContentView(R.layout.activity_main)
public class MainActivity extends BaseActivity {
@BindView(R.id.button1)
Button btn1;
@BindView(R.id.button2)
Button btn2;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//检测 控件注入 是否成功
btn1.setText("我是注入的按钮01");
btn2.setText("我是注入的按钮02");
}
}
下面还是见证奇迹的时刻:
怎么样是不是不撸不知道,一撸代码才知道原来这就是IOC技术啊,也蛮容易的嘛~
是的,布局注入和控件注入我们都轻松搞定啦。
还有一个事件注入我们没有实现,这个事件注入就会有点小难度了哟。
害怕文档太长,大家懒得看(PS:其实是因为我懒),
那我们就在下篇继续来撸代码一步一步实现 事件注入 吧~~~
积累点滴,做好自己~