简介(以下问题):
根据我的应用程序需求,我需要创建TabLayout和一个扩展FragmentStatePAgerAdapter
的ViewPager。 Viewpager包含一个单类型片段的列表,我们称之为ListFragment。
每个Fragment
都会显示一个RecyclerView
列表。
现在出现了进退两难的局面。我希望实现的目标是每个ViewModel
都有ListFragment
,其中包含LiveData<ArrayList>
的{{1}},同时跟踪其自身的片段列表以进行任何更改(ListFragment
列表可以更改(删除/插入/设置))
以下是App的图片表示:
注意:ListFragment和Fragment List可能令人困惑。含义为Fragment
,其中每个ListFragment都有ArrayList<ListFragment>
,其中包含ViewModel
。
现在事情变得复杂了:
1)如何为每个LiveData<ArrayList<Object>>
创建ViewModel
,以及在哪里存储这些ViewModel?
2)在创建片段列表(具有非确定性大小)时,我在哪里存储列表,以及如何监听其中的更改(例如,删除片段)?
这些问题都是建筑师的问题。我清楚地了解了如何实现ListFragment
,ViewModel
等等,但我很困惑,比如,存储,创建等等。
还没有架构的假设。它可能是一些MVVN或MVC。
答案 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
}
});
}
}