1. 使用背景
如果没用过ViewBinding, 可以先去了解下. Android ViewBinding的使用
对于findViewById和OnClick,大部分时候, 我们使用ButterKnife就可以了,但是呢,谷歌后面出了DataBinding和Viewbinding来解决findViewById的问题,用了这两个以后,估计大家也不会使用ButterKnife. 那么问题来了,OnClick怎么处理呢? 直接手写吗? 所以就写了一个针对Onclick处理的小插件. 如下图:
lib中使用 if else模式
2. 引用插件方式
File---settings---Plugins. 搜索OnClickMe
插件地址:https://plugins.jetbrains.com/plugin/14634-onclickme
3. 使用方式
和ButterKnife差不多,鼠标右键 选中布局(activity_main 或 ActivityMainBinding)---generate----OnClickMe.
项目首次使用建议, 勾选“生成解析类”,重新编译一下即可生成对应的类,生成的类在 src/java/liys/click下
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();
}
}
});
}
}
}
}
**如果还有什么更好的解决方法, 欢迎在下方评论留言