Архитектура FragmentStatePagerAdapter, ViewModel и список фрагментов - PullRequest
0 голосов
/ 12 июня 2018

Введение (Вопросы ниже): В требованиях моего приложения мне нужно создать TabLayout и ViewPager, расширяющий FragmentStatePAgerAdapter.Viewpager состоит из списка фрагментов одного типа, назовем его ListFragment.

Каждый Fragment отображает один список RecyclerView.

Теперь возникает дилемма.Чего я хочу добиться, так это иметь ViewModel для каждого ListFragment, который содержит LiveData<ArrayList> из ListFragment, в то же время продолжая отслеживать список фрагментов самостоятельно для любых изменений (список Fragment может бытьизменено (удалить / вставить / установить))

Вот изображение приложения:

Приложение

Примечание: ListFragment и Fragment Listможет быть запутанным.Значение имеет ArrayList<ListFragment>, где каждый ListFragment имеет ViewModel, который содержит LiveData<ArrayList<Object>>.

Теперь все становится просто сложнее:

1) Как мне создать ViewModel для каждого ListFragment, и где мне хранить эти ViewModels?

2)После создания списка фрагментов (с недетерминированным размером), где я могу сохранить список и как мне прослушать его изменения (например, удалить фрагмент)?

Все эти вопросы относятся к архитектуре,У меня есть четкое понимание того, как реализовать ViewModel, FragmentStatePagerAdapter и т. Д., Но я довольно смущен, например, где хранить, создавать и т. Д.

Нет предположения об архитектурееще.Это может быть MVVN или MVC.

1 Ответ

0 голосов
/ 18 июня 2018

Обратите внимание, что я несколько озадачен тем, чего именно вы пытаетесь достичь, но я попробую.

У меня будет только одна ViewModel, которая создается внутри действия, которое управляет всемиСписок фрагментов.В этом случае ViewModel будет иметь хеш-таблицу для хранения всех необходимых ему LiveData<ArrayList<Object>>.В качестве ключа хеш должен использовать индекс или фрагмент, к которому он принадлежит (предпочтительно последний).Когда фрагмент должен быть удален, вы вызываете метод remove, который удаляет индекс / фрагмент из хеш-таблицы.

Чтобы использовать ViewModel внутри фрагмента, Activity вставляет созданную им ViewModel во фрагмент.Таким образом, все фрагменты имеют одну и ту же модель представления.Будьте внимательны здесь, в каком порядке вы выполняете вещи.

public class ListsViewModel {
    private HashMap<Integer, MutableLiveData<ArrayList<Object>>> hash = new HashMap<>();

    public void setList(int index, ArrayList<Object> newList) {
        if (!hash.containsKey(index)) {
            throw new IllegalStateException("No such list.");
        }
        MutableLiveData<ArrayList<Object>> mutableLiveData = hash.get(index);
        mutableLiveData.setValue(newList);
    }

    public LiveData<ArrayList<Object>> getList(int index) {
        if (!hash.containsKey(index)) {
            hash.put(index, new MutableLiveData<ArrayList<Object>>());
        }
        return hash.get(index);
    }

    public void flush(Object key) {
        hash.remove(key);
    }
}

public interface IListFragment {
    public void setViewModel(ListsViewModel listVM, int index);
}

public class ListFragment extends Fragment implements IListFragment {

    private ListsViewModel vm;
    private int key; // might be needed later for cleanup

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Setup fragment

        someButton.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                vm.setList(aNewListOrOtherChanges);
            }
        }
    }

    @Override
    public void setViewModel(ListsViewModel listVM, int index) {
        this.vm = listVM;
        this.key = index;
        vm.getList(index).observe(this, new Observer<ArrayList<Object>>() {
            @Override
            public void onChanged(@Nullable ArrayList<Object> newList) {
                // Update UI
            }
        });
    }
}
...