Implementation Notes ways to register and click controls

Reference: https: //www.jianshu.com/p/20da6d6389e1

ViewInject.java

/**
 * @Retention 用于声明该注解生效的生命周期,有三个枚举值可以选择<br>
 * 1. RetentionPolicy.SOURCE 注释只保留在源码上面,编译成class的时候自动被编译器抹除
 * 2. RetentionPolicy.CLASS 注释只保留到字节码上面,VM加载字节码时自动抹除
 * 3. RetentionPolicy.RUNTIME 注释永久保留,可以被VM加载时加载到内存中
 * 注意:由于我们的目的是想在VM运行时对Filed上的该注解进行反射操作,因此Retention值必须设置为RUNTIME
 *
 * @Target 用于指定该注解可以声明在哪些成员上面,常见的值有FIELD和Method,
由于我们的当前注解类是想声明在Filed上面
 * 因此这里设置为ElementType.FIELD。
 * 注意:如果@Target值不设置,则默认可以添加到任何元素上,不推荐这么写。
 *
 * @interface 是声明注解类的组合关键字。
 */
@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface ViewInject {
    public abstract int value();
}

Onclick.java

@Target({java.lang.annotation.ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface Onclick {
    public abstract int[] value();
}

ViewUtils.java

public class ViewUtils {

    public static void inject(final Activity activity) {
        Class clazz = activity.getClass();

        Field[] declaredFields = clazz.getDeclaredFields();
        for (int i = 0; i < declaredFields.length; i++) {
            Field field = declaredFields[i];
            field.setAccessible(true);  //暴力访问

            ViewInject annotation = field.getAnnotation(ViewInject.class);
            if (annotation == null) {
                continue;
            }
            int id = annotation.value();
            View view = activity.findViewById(id);
            try {
                field.set(activity, view);
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
        }

        Method[] declaredMethods = clazz.getDeclaredMethods();
        for (int i = 0; i < declaredMethods.length; i++) {
            final Method method = declaredMethods[i];
            Onclick annotation = method.getAnnotation(Onclick.class);
            if (annotation == null) {
                continue;
            }

            int[] value = annotation.value();
            for (int j = 0; j < value.length; j++) {
                int id = value[j];
                final View button = activity.findViewById(id);
                button.setOnClickListener(new View.OnClickListener(){

                    @Override
                    public void onClick(View view) {
                        try {
                            method.invoke(activity,button);
                        } catch (IllegalAccessException e) {
                            e.printStackTrace();
                        } catch (InvocationTargetException e) {
                            e.printStackTrace();
                        }
                    }
                });
            }
        }

    }
}

Test class

public class Activity_InjectTest  extends AppCompatActivity {

    @ViewInject(R.id.btn_1)
    Button btn_1;

    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_inject);

        ViewUtils.inject(this);
    }

    @Onclick(R.id.btn_1)
    public void onClick(View view){
        switch (view.getId()){
            case R.id.btn_1:
                Log.e("dmj","btn_1");
                break;
        }
    }

}
Published 57 original articles · won praise 3 · Views 6211

Guess you like

Origin blog.csdn.net/qq_39830579/article/details/100513682