使用注解解放View的findViewbyId和setOnclickListener

通过注解可以减少很多重复的代码。比如findviewById,seonclickListener等。

1.创建BindView注解(用于成员变量,在运行时存在)

@Target(ElementType.FIELD)

@Retention(RetentionPolicy.RUNTIME)

public @interface BindView {

     int  value() default  -1;

}



2.创建Click注解(用于方法,在运行时存在)

@Target(ElementType.METHOD)

@Retention(RetentionPolicy.RUNTIME)

public @interface Click {

       int  value()  default  -1;

}


3.创建一个处理注解的静态类

public class AnnocationUtils {

    public static void analysisAnnocation(final Activity activity) {
        Class clazz = activity.getClass();
        Field[] fields = clazz.getDeclaredFields();
        for (Field field : fields) {
            if (field.isAnnotationPresent(BindView.class)) {
                BindView bindView = field.getAnnotation(BindView.class);
                int id = bindView.value();
                if (id > 0) {
                    field.setAccessible(true);
                    try {
                        field.set(activity, activity.findViewById(id));
                    } catch (IllegalAccessException e) {
                        e.printStackTrace();
                    }
                }
            }
        }

        Method[] methods = clazz.getDeclaredMethods();
        for (final Method method : methods) {
            if (method.isAnnotationPresent(Click.class)) {
                Click click = method.getAnnotation(Click.class);
                int id = click.value();
                if (id > 0) {
                    View view = activity.findViewById(id);
                    method.setAccessible(true);
                    view.setOnClickListener(new View.OnClickListener() {
                        @Override
                        public void onClick(View v) {
                            try {
                                method.invoke(activity);
                            } catch (IllegalAccessException e) {
                                e.printStackTrace();
                            } catch (InvocationTargetException e) {
                                e.printStackTrace();
                            }
                        }
                    });
                }
            }
        }
    }
}

主要的功能是:通过反射得到activity的成员变量和方法。再判断成员变量和方法是否被注解过了,如果被注解过了,就获取注解,得到id,判断是否大于1,最后成员变量的执行设置属性值(set),方法的执行方法(invoke)

 

在Activity中使用注解:

public class MainActivity extends AppCompatActivity {
    private String TAG = "MainActivity";

    @BindView(R.id.btn_click1)
    private Button btn_1;

    @BindView(R.id.btn_click2)
    private Button btn_2;

    @BindView(R.id.btn_click3)
    private Button btn_3;

    int REQUEST_PERMISSION_CODE = 1001;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        AnnocationUtils.analysisAnnocation(this);
        btn_1.setText("我是按钮1");
        btn_2.setText("我是按钮2");
        btn_3.setText("我是按钮3");
    }

    @Click(R.id.btn_click1)
    private void  onClick(){
        Log.e(TAG,"我是按钮11");
    }

    @Click(R.id.btn_click2)
    public void  onClick2(){
        Log.e(TAG,"我是按钮22");
    }

    @Click(R.id.btn_click3)
    protected void  onClick3(){
        Log.e(TAG,"我是按钮33");
    }

 

 

可以使用@SingleClick注解来防止多次点击。这个注解可以用在lambda表达式中,实现在一定时间内只响应一次点击事件。具体实现方法可以参考以下代码: ``` @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.METHOD}) public @interface SingleClick { long value() default 1000;//设置点击时间间隔,默认为1000毫秒 } public class ClickUtils { private static long lastClickTime = 0; public static boolean isFastClick(long intervalTime) { long time = System.currentTimeMillis(); if (time - lastClickTime < intervalTime) { return true; } else { lastClickTime = time; return false; } } } //使用注解 button.setOnClickListener(v -> { if (!ClickUtils.isFastClick(1000)) { //执行点击事件 } }); //注解处理器 public class SingleClickProcessor { public static void process(Object object) { Method[] methods = object.getClass().getDeclaredMethods(); for (Method method : methods) { SingleClick singleClick = method.getAnnotation(SingleClick.class); if (singleClick != null) { View view = getView(object, method); view.setOnClickListener(new SingleClickListener(singleClick.value(), method, object)); } } } private static View getView(Object object, Method method) { try { Class<?>[] parameterTypes = method.getParameterTypes(); if (parameterTypes.length == 1 && View.class.isAssignableFrom(parameterTypes[0])) { int[] resIds = method.getAnnotation(OnClick.class).value(); if (resIds.length == 1) { return ((Activity) object).findViewById(resIds[0]); } } } catch (Exception e) { e.printStackTrace(); } return null; } private static class SingleClickListener implements View.OnClickListener { private long intervalTime; private Method method; private Object object; public SingleClickListener(long intervalTime, Method method, Object object) { this.intervalTime = intervalTime; this.method = method; this.object = object; } @Override public void onClick(View v) { if (!ClickUtils.isFastClick(intervalTime)) { try { method.invoke(object, v); } catch (Exception e) { e.printStackTrace(); } } } } } //在Activity的onCreate方法中调用注解处理器 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); SingleClickProcessor.process(this); } ``` 这段代码中,通过自定义@SingleClick注解和ClickUtils工具类实现了防止多次点击的功能。在lambda表达式中使用时,可以将点击事件的实现放在if语句块中,通过调用ClickUtils.isFastClick()方法来判断是否满足点击时间的间隔要求。同时,通过注解处理器SingleClickProcessor来自动化处理注解,实现更便捷的使用方式。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值