我应该在 ViewHolder 的什么地方取消绑定 ButterKnife 8.x.x?

Where should I unbind ButterKnife 8.x.x in a ViewHolder?

我有一个使用 ButterKnife 注释的 RecycleView.ViewHolder class。

我的代码也应该在此 ViewHolder class 中取消绑定()吗?

public class AView extends RecyclerView.ViewHolder
{
    @BindView(R.id.a_text_view) TextView aText;

    public AView(final View view)
    {
        super(view);
        ButterKnife.bind(this, view); // It returns an Unbinder, but where should I call its unbind()?
    }
}

文档 (http://jakewharton.github.io/butterknife/) 没有讨论这个问题。

Yes, they do。 这仅适用于 Fragments。

文档中有一个示例,演示了如何在 ViewHolder 中使用此库:

static class ViewHolder {
    @BindView(R.id.title) TextView name;
    @BindView(R.id.job_title) TextView jobTitle;

    public ViewHolder(View view) {
      ButterKnife.bind(this, view);
    }
  }

因此,无需为您的 ViewHolder 调用解除绑定。

以下是何时以及为何使用 unbind() 方法的说明:

BINDING RESET

Fragments have a different view lifecycle than activities. When binding a fragment in onCreateView, set the views to null in onDestroyView. Butter Knife returns an Unbinder instance when you call bind to do this for you. Call its unbind method in the appropriate lifecycle callback.

public class FancyFragment extends Fragment {
  @BindView(R.id.button1) Button button1;
  @BindView(R.id.button2) Button button2;
  private Unbinder unbinder;

  @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.fancy_fragment, container, false);
    unbinder = ButterKnife.bind(this, view);
    // TODO Use fields...
    return view;
  }

  @Override public void onDestroyView() {
    super.onDestroyView();
    unbinder.unbind();
  }
}

From: http://jakewharton.github.io/butterknife/#reset

所以您根本不需要 unbind 来自 ViewHolder 的任何视图。

希望对您有所帮助

根据 Butterknife 的作者 Jake Wharton 的说法,只有 Fragments 才需要 unbind()。在问题跟踪器上查看此评论:

https://github.com/JakeWharton/butterknife/issues/879

Q: In the RecyclerView, how do we unbind the ViewHolder?

A: You don't need to. Only Fragments need to in onDestroyView().

原因是

[ViewHolders] don't outlive the associated view. A Fragment does.

也就是说,因为一个Fragment在它的Views被销毁后可能会继续存在,所以你需要从一个Fragment调用.unbind()来释放引用到 Views(并允许回收关联的内存)。

对于ViewHolder,持有者的生命周期与其持有的Views相同。换句话说,ViewHolder 及其 Views 同时被销毁,因此永远不会有您需要手动清除的从一个到另一个的挥之不去的引用。

就用它吧:

@Override
public void onDetachedFromRecyclerView(@NonNull RecyclerView recyclerView) {
    if (unbinder != null) {
        unbinder.unbind();
    }
}

Jakewharton 在他的文档中明确提到

https://jakewharton.github.io/butterknife/

Unbind 应该只为片段调用,最重要的是,它应该在 onDestroyView 而不是 DestroyView 中调用。