问题
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 theViewHolder
?A: You don't need to. Only
Fragments
need to inonDestroyView()
.
The reason being that
[
ViewHolders
] don't outlive the associated view. AFragment
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 inonDestroyView
. Butter Knife returns anUnbinder
instance when you callbind
to do this for you. Call itsunbind
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