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();
                            }
                        }
                    });
                }
            }
        }
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章