ButterKnife框架源码分析

一.注册
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);
      }
}



最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容