将BindView与Butterknife一起使用的反面是什么?

时间:2018-04-30 22:05:48

标签: android

我试图在不使用Butterknife方法的情况下编写以下代码,主要用于学习目的。任何人都可以帮助你写它而不用它吗?

我猜它有点像

TextView textName = findViewById(R.id.post_title); 

但似乎运行不一样所以我猜我错过了什么

public class FriendsHolder extends RecyclerView.ViewHolder {
    @BindView(R.id.name)
    TextView textName;
    @BindView(R.id.image)
    CircleImageView imageView;
    @BindView(R.id.title)
    TextView textTitle;
    @BindView(R.id.company)
    TextView textCompany;

    public FriendsHolder(View itemView) {
        super(itemView);
        ButterKnife.bind(this, itemView);
    }
}

2 个答案:

答案 0 :(得分:4)

当编译SDK版本大于或等于26时,您可以采用以下方法:

public class FriendsHolder extends RecyclerView.ViewHolder {
    TextView textName;
    CircleImageView imageView;
    TextView textTitle;
    TextView textCompany;

    public FriendsHolder(View itemView) {
        super(itemView);
        textName = itemView.findViewById(R.id.name);
        imageView = itemView.findViewById(R.id.image);
        textTitle = itemView.findViewById(R.id.title);
        textCompany = itemView.findViewById(R.id.company);
    }
}

对于小于26的API版本,您只需要将findViewById方法返回的视图明确类型转换为字段类型。

答案 1 :(得分:3)

正如您可能知道的那样,ButterKnife是一个注释处理器,它在编译时获取您的代码,评估注释(例如。@BindView)并生成代码以替换它们。

现在,在@BindView的情况下,注释处理器实际上做的是:

  1. 按ID ID
  2. 查找所需的视图

    1. 将其投射到预期的类型。
    2. 所以你的例子的功能相当于:

      public class FriendsHolder extends RecyclerView.ViewHolder {
      
          private TextView textName;
          private CircleImageView imageView;
          private TextView textTitle;
          private TextView textCompany;
      
          FriendsHolder(View itemView) {
              super(itemView);
              bindViews(itemView);
          }
      
          private void bindViews(View root) {
              textName = (TextView) root.findViewById(R.id.name);
              imageView = (CircleImageView) root.findViewById(R.id.image);
              textTitle = (TextView) root.findViewById(R.id.title);
              textCompany = (TextView) root.findViewById(R.id.company);
          }
      }
      

      您可以详细了解基础流程in this blog post或查看some of the ButterKnife source code

      你可以看到他们所做的基本上是在源视图上查找ID,并尝试将其转换为从带注释的字段中读取的预期类型。

      摘录自butterknife.internal.Utils

      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 View findRequiredView(View source, @IdRes int id, String who) {
          View view = source.findViewById(id);
          if (view != null) {
            return view;
          }
          // If view is null throw IllegalStateException
      }
      
      public static <T> T castView(View view, @IdRes int id, String who, Class<T> cls) {
          try {
            return cls.cast(view); // <-- casting 
          } catch (ClassCastException e) {
              throw new IllegalStateException
              // Exception handling...
          }