自定义注解结合反射实现绑定布局控件点击事件

本文介绍了一种通过自定义注解和反射技术来动态绑定布局中的控件点击事件的方法,实现了代码的简洁性和可维护性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

ContentView

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
@Inherited
public @interface ContentView {
    int value();
}
BindView

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
@Documented
@Inherited
public @interface BindView {
    int value();
}
OnClick

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@Documented
@Inherited
public @interface OnClick {
    int [] value();
}
MainActivity

@ContentView(R.layout.activity_main)
public class MainActivity extends AppCompatActivity {
    @BindView(R.id.tv)
    TextView textView;
    @BindView(R.id.sdv)
    SimpleDraweeView sdv;
    @BindView(R.id.tv1)
    TextView textView1;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Utils.setContent(this);
        initView();
    }

    private void initView() {
        textView.setText("hahaha");
        textView1.setText("hehehe");
        Uri uri = Uri.parse("https://m.360buyimg.cqweom/n0/jfs/t6130/97/1370670410/180682/1109582a/593276b1Nd81fe723.jpg!q70.jpg");
        sdv.setImageURI(uri);
        DraweeController build = Fresco.newDraweeControllerBuilder()
                .setUri(uri)
                .setOldController(sdv.getController())
                .setTapToRetryEnabled(true).build();
        sdv.setController(build);
    }
    @OnClick(R.id.tv)
    public void aa(){
        Toast.makeText(MainActivity.this,"hehe",Toast.LENGTH_SHORT).show();
    }
    @OnClick(R.id.sdv)
    public void bb(){
        Toast.makeText(MainActivity.this,"haha",Toast.LENGTH_SHORT).show();
    }
@OnClick(R.id.tv1)
    public void cc(){
    Toast.makeText(MainActivity.this,"haha",Toast.LENGTH_SHORT).show();
}

}
Utils

public class Utils {
    public static void setContent(Activity activity){
        setcontentview(activity);
        setbindview(activity);
        setonclick(activity);
    }

    public static void setcontentview(Activity activity) {
        Class clazz = activity.getClass();
        ContentView annotation = (ContentView) clazz.getAnnotation(ContentView.class);
        int value = annotation.value();
        try {
            Method method = clazz.getMethod("setContentView", int.class);
            method.invoke(activity,value);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static void setbindview(Activity activity) {
        Class clazz = activity.getClass();
        Field[] fields = clazz.getDeclaredFields();
        if(fields!=null&&fields.length>0){
            for (Field field : fields) {
                field.setAccessible(true);
                BindView bindView = field.getAnnotation(BindView.class);
                int value = bindView.value();
                    View view = activity.findViewById(value);
                    try {
                        field.set(activity,view);
                    } catch (IllegalAccessException e) {
                        e.printStackTrace();
                }
            }
        }

    }

    public static void setonclick(final Activity activity) {
        Class clazz = activity.getClass();//第一种方式
        Class clazz2 = Activity.class;//第二种方式
        try {
            Class aClass = Class.forName("com.lixinyang.myreflect.MainActivity");//第三种方式
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        //获取到里面的所有方法
        Method[] methods = clazz.getMethods();
        //foueach进行循环遍历
        for (final Method method : methods) {
            OnClick click = method.getAnnotation(OnClick.class);//通过反射api获取方法上面的注解
            if (click != null) {
                int[] value = click.value();
                for (int i : value) {
                    if (i == -1) return;
                    View view = activity.findViewById(i);//通过注解的值获取View控件
                    if (view == null) return;
                    view.setOnClickListener(new View.OnClickListener() {
                        @Override
                        public void onClick(View v) {
                            try {
                                method.invoke(activity);//通过反射来调用被注解修饰的方法
                            } catch (Exception e) {
                                e.printStackTrace();
                            }
                        }
                    });
                }

            }
        }
    }
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值