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

邮差的信 提交于 2019-12-03 06:38:59

问题


I have a RecycleView.ViewHolder class which use ButterKnife annotations.

Should my code unbind() in this ViewHolder class too?

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()?
    }
}

The docs (http://jakewharton.github.io/butterknife/) does not talk about this issue.


回答1:


According to Jake Wharton, author of Butterknife, unbind() is only required for Fragments. See this comment on the issue tracker:

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().

The reason being that

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

In other words, because a Fragment may continue to exist after its Views are destroyed, you need to call .unbind() from a Fragment to release the reference to the Views (and allow the associated memory to be reclaimed).

With a ViewHolder, the lifecycle of the holder is the same as the Views it holds. In other words, the ViewHolder and its Views are destroyed at the same time, so there's never a lingering reference from one to the other that you need to manually clear.




回答2:


Here's an explanation WHEN and WHY to use unbind() method:

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

so you don't need at all to unbind any view from ViewHolder.

Hope it will help




回答3:


There is an example in the doc, which demonstrates how to use this library in the 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);
    }
  }

So, there is no need to call unbind for your ViewHolder.




回答4:


Yes, they do. This is only needed for Fragments.




回答5:


Just use it :

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



回答6:


Jakewharton has mentioned clearly in his documention

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

Unbind should be called only for fragments and most importantly , it should be called in onDestroyView instead of DestroyView .



来源:https://stackoverflow.com/questions/38015412/where-should-i-unbind-butterknife-8-x-x-in-a-viewholder

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!