一.注册
public abstract class SettingActivity extends AppCompatActivity {
protected void onCreate(@Nullable Bundle savedInstanceState) {
ButterKnife.bind(this);
}
}
二.获取DecorView
public static Unbinder bind(@NonNull Activity target) {
View sourceView = target.getWindow().getDecorView(); //获取DecorView
return bind(target, sourceView);
}
三.反射获取SettingActivity_ViewBinding构造方法
- constructor.newInstance 调用构造方法,创建SettingActivity_ViewBinding实例
public static Unbinder bind(@NonNull Object target, @NonNull View source) {
Class<?> targetClass = target.getClass();
//反射方式得到SettingActivity_ViewBinding的构造方法
Constructor<? extends Unbinder> constructor = findBindingConstructorForClass(targetClass);
if (constructor == null) {
return Unbinder.EMPTY;
}
//调用SettingActivity_ViewBinding(final SettingActivity target, View source)
return constructor.newInstance(target, source);
}
- findBindingConstructorForClass(targetClass)具体实现
private static Constructor<? extends Unbinder> findBindingConstructorForClass(Class<?> cls) {
Class<?> bindingClass = cls.getClassLoader().loadClass(clsName + "_ViewBinding");
bindingCtor = (Constructor<? extends Unbinder>) bindingClass.getConstructor(cls, View.class);
return bindingCtor;
}
四.SettingActivity_ViewBindings实现
- 核心是通过docorView.findviewById获取view
- 将获取到的view castView 为LinearLayout对象,赋值给target.ll_language 变量.
- 给view设置点击事件,通过target.onViewClick进行回调.
@UiThread
public SettingActivity_ViewBinding(final SettingActivity target, View source) {
View view;
//获取View
view = Utils.findRequiredView(source, R.id.ll_language, "field 'll_language' and method 'onViewClicked'");
//把View转换成LinearLayout
target.ll_language = Utils.castView(view, R.id.ll_language, "field 'll_language'", LinearLayout.class);
//给ll_language 设置点击事件
view.setOnClickListener(new DebouncingOnClickListener() {
@Override
public void doClick(View p0) {
target.onViewClicked(p0); //回调SettingActivity.onViewClicked
}
});
target.tv_language = Utils.findRequiredViewAsType(source, R.id.tv_language, "field 'tv_language'", TextView.class);
}
五.Utils类
- findRequiredView 核心还是findViewById
public final class Utils {
public static View findRequiredView(View source, @IdRes int id, String who) {
View view = source.findViewById(id); //核心
if (view != null) {
return view;
}
}
public static <T> T findRequiredViewAsType(View source, @IdRes int id, String who, Class<T> cls) {
View view = findRequiredView(source, id, who);
return castView(view, id, who, cls);
}
public static <T> T castView(View view, @IdRes int id, String who, Class<T> cls) {
return T(view);
}
}