构建FragmentStatePagerAdapter,ViewModel和Fragment列表

时间:2018-06-12 12:27:36

标签: android android-fragments android-viewpager viewmodel

简介(以下问题): 根据我的应用程序需求,我需要创建TabLayout和一个扩展FragmentStatePAgerAdapter的ViewPager。 Viewpager包含一个单类型片段的列表,我们称之为ListFragment。

每个Fragment都会显示一个RecyclerView列表。

现在出现了进退两难的局面。我希望实现的目标是每个ViewModel都有ListFragment,其中包含LiveData<ArrayList>的{​​{1}},同时跟踪其自身的片段列表以进行任何更改(ListFragment列表可以更改(删除/插入/设置))

以下是App的图片表示:

App

注意:ListFragment和Fragment List可能令人困惑。含义为Fragment,其中每个ListFragment都有ArrayList<ListFragment>,其中包含ViewModel

现在事情变得复杂了:

1)如何为每个LiveData<ArrayList<Object>>创建ViewModel,以及在哪里存储这些ViewModel?

2)在创建片段列表(具有非确定性大小)时,我在哪里存储列表,以及如何监听其中的更改(例如,删除片段)?

这些问题都是建筑师的问题。我清楚地了解了如何实现ListFragmentViewModel等等,但我很困惑,比如,存储,创建等等。

还没有架构的假设。它可能是一些MVVN或MVC。

1 个答案:

答案 0 :(得分:1)

请注意,我对你想要达到的目标感到有些困惑,但我会试一试。

我只有一个ViewModel,它是在管理所有List片段的活动中创建的。然后,ViewModel将具有用于存储其所需的所有LiveData<ArrayList<Object>>的哈希表。作为键,哈希应该使用索引或它所属的片段(最好是后者)。当应该删除片段时,您调用remove方法,该方法从哈希表中删除索引/片段。

要在片段内使用ViewModel,Activity会将它创建的ViewModel注入Fragment。这样,所有片段共享相同的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
            }
        });
    }
}