系列文章
IoC之手写运行时注入布局
IoC之手写运行时注入控件
IoC之手写运行时注入点击事件
IoC之手写运行时注入通用事件
前言
上篇文章中,我们介绍了运行时注入布局,这篇文章我们将介绍如何在运行期注入控件,也就是运行期实例化控件。
注入控件
首先我们仍然需要一个注解,去获取需要在运行期实例化的变量及其id
@Target(ElementType.FIELD) // 作用域我们字段上
@Retention(RetentionPolicy.RUNTIME)
public @interface BindView {
int value() default -1;
}
然后我们写一个静态方法来处理
public class InjectTool {
private static final String TAG = InjectTool.class.getSimpleName();
public static void inject(Object object) {
injectSetContentView(object);
injectBindView(object);
}
}
/**
* 把一系列控件注入到 Activity中去
* @param object == MainActivity
*/
private static void injectBindView(Object object) {
Class<?> mainActivityClass = object.getClass();
// TODO 遍历MainActivity里面所有的注解 (字段上的)
// 遍历 MainActivity里面所有的字段
Field[] fields = mainActivityClass.getDeclaredFields();
for (Field field : fields) { // Button button1; TextView textView; String string;
field.setAccessible(true);
BindView bindView = field.getAnnotation(BindView.class);
if (null == bindView) {
Log.d(TAG, "BindView is null");
continue; // 结束本次循环,进入下一个循环
}
// get R.id.bt_test1
int viewID = bindView.value();
// 把控件给实例化出来
// button1 = findViewById(R.id.bt_test1);
try {
Method findViewByIdMethod = mainActivityClass.getMethod("findViewById", int.class);
Object resultView = findViewByIdMethod.invoke(object, viewID); // 执行此函数---findViewById(R.id.bt_test1);
// 给我们的字段,字段赋值了
// button1 = findViewById(R.id.bt_test1);
// filed = findViewById(viewID);
field.set(object, resultView);
} catch (Exception e) {
e.printStackTrace();
}
}
}
最后我们再Activity中调用这个方法。
@ContentView(R.layout.activity_main) // 5415151
public class MainActivity extends AppCompatActivity {
@BindView(R.id.bt_test1)
Button button1;
TextView textView;
String string;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
InjectTool.inject(this);
Log.d("MainActivity", "onCreate: " + button1.getText().toString());
}
}