Android UI IoC注解加载控件

知识点:注解 反射

接上篇 Android UI IoC注解加载布局

1. 业务Activity 和注解 InjectView
// 普通页面Activity代码,正常启动即可正常加载ioc_act.xml
@ContentView(R.layout.ioc_act)
public class IocAct extends BaseActivity {
    
    @InjectView(R.id.tv)
    private TextView tv;

    @Override
    protected void onResume() {
        super.onResume();
        // 也是通过注解加载tv(类ButterKnife原理)
        // TextView tv = findViewById(R.id.tv);
        Toast.makeText(this, tv.getText().toString(), Toast.LENGTH_SHORT)
        .show();
    }
}
// 该注解作用于属性
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface InjectView {
    int value();
}

2. 业务ioc_act.xml ,BaseActivity.java实现同上篇
3. InjectManager实现控件注入
public class InjectManager {

    public static void inject(Activity activity) {
        // 布局的注入
        injectLayout(activity);
        // 控件的注入
        injectViews(activity);
    }

    // 布局的注入
    private static void injectLayout(Activity activity) {
        ......
    }

    // 控件的注入
    private static void injectViews(Activity act) {
        // 获取类
        Class<? extends Activity> clazz = act.getClass();
        // 获取类的所有属性
        Field[] fields = clazz.getDeclaredFields();
        // 循环每个属性
        for (Field field : fields) {
            // 获得属性上的注解
            InjectView injectView = field.getAnnotation(InjectView.class);
            // 获取注解的值
            if (injectView != null) { // 并不是所有的属性都有注解
                int viewId = injectView.value();
                // 获取findViewById方法,并执行
                try {
                    Method method = clazz.getMethod("findViewById", int.class);
                    Object view = method.invoke(act, viewId);
                    // 另一种写法:
                    // view = activity.findViewById(viewId);
                    // 设置访问权限private
                    field.setAccessible(true);
                    field.set(act, view); // 属性的值赋给控件,在当前Activity
                } catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

概括:其实上面几步就是ButterKnife的实现原理,免去大量findViewById之类的代码

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐