OnClickMe一款自動生成OnClick代碼的插件

1. 使用背景

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

對于findViewById和OnClick,大部分時候, 我們使用ButterKnife就可以了,但是呢,谷歌后面出了DataBinding和Viewbinding來解決findViewById的問題,用了這兩個以后,估計大家也不會使用ButterKnife. 那么問題來了,OnClick怎么處理呢? 直接手寫嗎? 所以就寫了一個針對Onclick處理的小插件. 如下圖:

OnClickMe.gif

lib中使用 if else模式

if else模式.gif

2. 引用插件方式

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

1594086344(1).png

插件地址:https://plugins.jetbrains.com/plugin/14634-onclickme

3. 使用方式

和ButterKnife差不多,鼠標右鍵 選中布局(activity_main 或 ActivityMainBinding)---generate----OnClickMe.

彈框.png


項目首次使用建議, 勾選“生成解析類”,重新編譯一下即可生成對應的類,生成的類在 src/java/liys/click下

注解類和解析類.png

OnClickUtils.init(Activity activity); //Activity中使用
OnClickUtils.init(Object target, View view); //Fragment或其它地方使用
4. 總結

主要配合databinding或Viewbinding使用

5. 疑問

解析使用的是反射,可能有人會說影響性能,其實這點性能對體驗是感覺不到的,如果像ButterKnife一樣自動生成一個類去解析,為了一個Onclick的功能而特意生成一個類,我覺得有點大材小用了,最終選擇了反射.

生成的 OnClick和OnClickUtils 源碼如下:
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface OnClick {
    @IdRes int[] value() default { View.NO_ID };
}
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){
        final Method[] methods = target.getClass().getDeclaredMethods();
        for (int i = 0; i < methods.length; i++) {
            boolean hasAnno = methods[i].isAnnotationPresent(OnClick.class);
            if(!hasAnno){
                continue;
            }
            OnClick onClick = methods[i].getAnnotation(OnClick.class);
            int[] ids = onClick.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 e) {
                            e.printStackTrace();
                        } catch (InvocationTargetException e) {
                            e.printStackTrace();
                        }
                    }
                });
            }
        }
    }
}

**如果還有什么更好的解決方法, 歡迎在下方評論留言

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

友情鏈接更多精彩內容