Где я должен отпереть ButterKnife 8.x.x в ViewHolder?
У меня есть класс RecycleView.ViewHolder, который использует аннотации ButterKnife.
Должен ли мой код unbind() в этом классе ViewHolder тоже?
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/) не говорят об этой проблеме.
Ответы
Ответ 1
По словам Джейка Уортона, автор Butterknife, unbind()
требуется только для Fragments
. См. Этот комментарий к трекеру вопросов:
https://github.com/JakeWharton/butterknife/issues/879
Q: В RecyclerView
, как мы отвязаем ViewHolder
?
A: Вам не нужно. Только Fragments
нужно в onDestroyView()
.
Причина в том, что
[ViewHolders
] не ожидают связанного представления. A Fragment
.
Другими словами, поскольку a Fragment
может продолжать существовать после уничтожения его Views
, вам нужно вызвать .unbind()
из Fragment
, чтобы освободить ссылку на Views
(и разрешить связанный память будет восстановлена).
При ViewHolder
жизненный цикл держателя совпадает с Views
. Другими словами, ViewHolder
и его Views
уничтожаются одновременно, поэтому никогда не существует затяжной ссылки от одной к другой, которую нужно вручную очистить.
Ответ 2
Здесь объяснение WHEN и WHY использовать метод unbind()
:
BINDING RESET
Фрагменты имеют иной жизненный цикл представления, чем действия. когда связывание фрагмента в onCreateView
, установите представления в null в onDestroyView
. Butter Knife возвращает экземпляр Unbinder
, когда вы вызовите bind
, чтобы сделать это для вас. Вызовите его метод unbind
в соответствующий обратный вызов жизненного цикла.
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();
}
}
От: http://jakewharton.github.io/butterknife/#reset
поэтому вам совсем не нужно unbind
любого вида из ViewHolder
.
Надеюсь, что это поможет
Ответ 3
В документе есть пример, который демонстрирует, как использовать эту библиотеку в 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);
}
}
Таким образом, нет необходимости вызывать unbind для вашего ViewHolder.
Ответ 4
Да, они делают.
Это необходимо только для фрагментов.
Ответ 5
Просто используйте это:
@Override
public void onDetachedFromRecyclerView(@NonNull RecyclerView recyclerView) {
if (unbinder != null) {
unbinder.unbind();
}
}
Ответ 6
Джейквартон четко упомянул в своей документации
https://jakewharton.github.io/butterknife/
Unbind следует вызывать только для фрагментов и, что самое важное, вызывать его в onDestroyView вместо DestroyView.