Может / должен ли RecyclerView.Adapter иметь доступ к ViewHolders?

android android-recyclerview android-view android-adapter

1475 просмотра

1 ответ

У меня есть EditTextв каждом View, и onViewRecycled(.)я обновляю элемент в Adapterлюбой пользовательский ввод. В целях сохранения информации при прокрутке Viewsиз и обратно в поле зрения.

Однако я понял, что с этим решением немного хлопотно получать информацию, которая была изменена, но не переработана. Я решил эту проблему, добавив каждый из них ViewHolderв отдельный список Adapter(добавлен в onCreateViewHolder(.)), так как не смог найти более простой способ обновления Viewsна экране.

Есть ли причина не делать этого; позвольте Adapterиметь прямой доступ к ViewHolders? Т.е. есть ли лучшие способы вызвать функцию для всех Viewsсуществующих в настоящее время?

Редактировать:

public class AdapterRv extends Adapter<AdapterRv.MyViewHolder> {
    private List<Item> items;
    private List<MyViewHoders> viewHolders;

    public AdapterRv(List<Item> inItems) {
        ...

        viewHolders = new ArrayList<>();
    }

    public class MyViewHolder extends RecyclerView.ViewHolder {
        private EditText text;
        private Item item;

        private MyViewHolder(View inView) {
            ...
        }

        public void bindItem(Item inItem) {
            ...
        }
    }

    @Override
    public MyViewHolder onCreateViewHolder(ViewGroup inParent, int inViewType) {
        ...

        if (!viewHolders.contains(tmpHolder)) {
            viewHolders.add(tmpHolder);
        }

        ...
    }

    ....

    @Override
    public void onViewRecycled(MyViewHolder inViewHolder) {
        saveView(inViewHolder.item, inViewHolder.text.getText().toString());
    }

    private void saveViews() {
        for (MyViewHolder tmpViewHolder : viewHolders) {
            saveView(tmpViewHolder.item, tmpViewHolder.text.getText().toString());
        }
    }

    private void saveView(Item inItem, String inNewText) {
        if (inItem.getText().equals(inNewText)) {
            return;
        }
        inItem.setText(inNewText);
    }

    public List<Item> fetchTexts() {
        saveViews();
        return items;
    }
}
Автор: Fred Источник Размещён: 08.11.2019 11:22

Ответы (1)


3 плюса

Решение

Цель RecyclerView.Adapterсостоит только в том, чтобы создавать ViewHolderэкземпляры и предоставлять им данные, но именно они RecyclerViewзапрашивают владельцев и управляют ими.

Цель ViewHolder, как следует из названия, состоит в том, чтобы сохранить иерархию представления элемента, чтобы его Viewsможно было кэшировать и использовать повторно RecyclerView. Следовательно, адаптер должен только создавать и связывать правильные данные с держателями, и рекомендуется не хранить никаких ссылок на держатели внутри адаптера, так как вам нужна только ссылка на держатель в onBindViewHolder(ViewHolder holder, int positionметоде, если он предоставлен RecyclerView. И наоборот, держатели просмотра не нуждаются в ссылке на адаптер, поэтому вы MyViewHolderдолжны быть помечены static.

Если вам нужно работать с представлениями переработчика, RecyclerViewв его API есть множество методов, таких как findViewHolderForLayoutPosition(int position)и getChildViewHolder(View child)т. Д. Вы также можете настроить прослушиватели для наблюдения за изменениями прокрутки, касания элемента, просмотра состояния присоединения и т. Д. Смотрите документацию для RecyclerView

Итак, если вам необходимо получить доступ к представлениям и манипулировать ими (т. Е. Вызывать функцию для всех представлений переработчика), делайте это через RecyclerViewадаптер, а не через адаптер, потому что им управляет переработчик - адаптер предоставляет только данные.

Автор: maciekjanusz Размещён: 20.08.2016 04:11
Вопросы из категории :
32x32