OnClickMe 一款自动生成OnClick代码的插件(2.0系列)

敬请期待....
可以先参考:https://www.jianshu.com/p/e6912e9069d3

一. 使用背景

如果没用过ViewBinding, 可以先去了解下. Android ViewBinding的使用

对于findViewById和OnClick,大部分时候, 我们使用ButterKnife就可以了,但是呢,谷歌后面出了DataBinding和Viewbinding来解决findViewById的问题,用了这两个以后,估计大家也不会使用ButterKnife. 那么问题来了,OnClick怎么处理呢? 直接手写吗? 所以就写了一个针对Onclick处理的小插件. 如下图:

解决的问题:
1. 每次都需要手动写重复的代码.
2. 在lib中,id无法用Switch(viewId)

二. 引用插件方式

File---settings---Plugins. 搜索OnClickMe


如果Android studio搜索不到插件?
点击File | Settings | Appearance & Behavior | System Settings | Updates 记住 Use secure connection(不要勾选),如果勾选就取消,然后重启

三. 使用方式

①. 和ButterKnife差不多,鼠标右键 选中布局(activity_main 或 ActivityMainBinding)---generate----OnClickMe.

②.项目首次使用, 需要勾选“生成解析类”,重新编译一下即可生成对应的类,生成的类在 src/java/liys/click下

OnClickUtils.init(Activity activity); //Activity中使用
OnClickUtils.init(Object target, View view); //Fragment或其它地方使用
四.关于性能问题

解析使用的是反射,原因有3个:

  1. 一般的App,一个页面能有多少个点击监听?用不用反射,我们人体是察觉不到有什么变化的.
  2. 手机硬件也在不断的升级,影响只会越来越小.
  3. 可以节约一些开发时间.
五.工具类源码
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface AClick {
    @IdRes int[] value() default { View.NO_ID };
}
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface AClickStr {
    String[] value() default {""};
}
public class OnClickUtils {

    public static void init(Activity target){
        View sourceView = target.getWindow().getDecorView();
        initClick(target, sourceView);
    }
    public static void init(Object target, View view){
        initClick(target, view);
    }
    private static void initClick(@NonNull final Object target, @NonNull View source){
        String packageName = source.getContext().getPackageName();
        final Method[] methods = target.getClass().getDeclaredMethods();
        for (int i = 0; i < methods.length; i++) {
            boolean hasAnno = methods[i].isAnnotationPresent(AClick.class);
            if(hasAnno){
                AClick aClick = methods[i].getAnnotation(AClick.class);
                assert aClick != null;
                int[] ids = aClick.value();
                for (int j = 0; j < ids.length; j++) {
                    final int finalI = i;
                    source.findViewById(ids[j]).setOnClickListener(new View.OnClickListener() {
                        @Override
                        public void onClick(View v) {
                            try {
                                methods[finalI].invoke(target, v);
                            } catch (IllegalAccessException | InvocationTargetException e) {
                                e.printStackTrace();
                            }
                        }
                    });
                }
            }
            boolean hasAnnoStr = methods[i].isAnnotationPresent(AClickStr.class);
            if(hasAnnoStr){
                AClickStr aClick = methods[i].getAnnotation(AClickStr.class);
                final String[] ids = aClick.value();
                for (int j = 0; j < ids.length; j++) {
                    final int finalI = i;
                    int id = 0;
                    try {
                        Class clazz = Class.forName(packageName+".R$id");
                        Field field = clazz.getDeclaredField(ids[j]);
                        id = (int)field.get(null);
                    } catch (ClassNotFoundException | IllegalAccessException | NoSuchFieldException e) {
                        e.printStackTrace();
                    }
                    if(id==0){
                        continue;
                    }
                    final int finalJ = j;
                    source.findViewById(id).setOnClickListener(new View.OnClickListener() {
                        @Override

                        public void onClick(View v) {
                            try {
                                methods[finalI].invoke(target, v, ids[finalJ]);
                            }catch (IllegalAccessException | InvocationTargetException e) {
                                e.printStackTrace();
                            }
                        }
                    });
                }
            }
        }
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章