架构FragmentStatePagerAdapter,ViewModel和一个Fragment列表 [英] Architecting FragmentStatePagerAdapter, ViewModel and a Fragment list

查看:95
本文介绍了架构FragmentStatePagerAdapter,ViewModel和一个Fragment列表的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Intro (Questions below): On my application demands, I need to create TabLayout and a ViewPager extending FragmentStatePAgerAdapter. The Viewpager consists of a list of one-type fragment, let's call it ListFragment.

每个 Fragment 显示一个 RecyclerView 列表.

现在进入了困境.我希望实现的是,为每个 ListFragment 使用一个 ViewModel ,其中包含 ListFragment 的 LiveData< ArrayList> code>,同时继续跟踪片段列表的自身变化( Fragment 列表可以更改(删除/插入/设置))

Now comes the dilemma. What I wish to achieve, is having a ViewModel for each ListFragment, which contains the LiveData<ArrayList> of the ListFragment while keep tracking the of list of fragments its self for any changes (the Fragment list can be changed (remove/insert/set))

以下是该应用程序的图片表示形式:

Here is a picture representation of the App:

应用

注意:ListFragment和Fragment List可能会造成混淆.含义是具有一个 ArrayList< ListFragment> ,其中每个ListFragment具有一个 ViewModel ,其中包含一个 LiveData< ArrayList< Object>> .

Note: The ListFragment and Fragment List could be confusing. The meaning is having a ArrayList<ListFragment>, where each ListFragment has a ViewModel that holds a LiveData<ArrayList<Object>>.

现在事情变得复杂了:

1)如何为每个 ListFragment 创建一个 ViewModel ,并将这些ViewModel存储在哪里?

1)How do I create a ViewModelfor each ListFragment, And where do I store those ViewModels?

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

2)Upon creating a Fragment List (with a non deterministic size), where do I store the List, and how do I listen to changes in it(like, removing a fragment)?

这些问题都是针对架构师的.我对如何实现 ViewModel FragmentStatePagerAdapter 等具有清楚的了解,但是我对诸如在何处存储,创建等感到困惑.

These questions are all Architect-wise. I have clear understanding of how to implement ViewModel, FragmentStatePagerAdapter and so on, but I am rather confused of, like, where to store, create and so on.

尚无架构的假设.可能是一些MVVN或MVC.

There is no assumption of an Architecture yet. It could be some MVVN or MVC.

推荐答案

请注意,对于您要实现的目标我有些困惑,但是我会给您一个机会.

Note that I'm somewhat confused over what exactly you are trying to achieve, but I'll give it a shot.

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

I would have only one ViewModel which is created inside the activity that manages all the List fragments. The ViewModel would then have a hashtable used for storing all the LiveData<ArrayList<Object>> that it needs. As a key the hash should either use an index or the fragment it belongs to (preferably the latter). When a fragment should be removed you call a remove method which removes the index/fragment from the hashtable.

要在片段中使用ViewModel,Activity会将其创建的ViewModel注入到Fragment中.这样,所有片段都共享相同的ViewModel.在这里要注意执行顺序.

To use the ViewModel inside the fragment the Activity injects the ViewModel it has created to the Fragment. That way all fragments share the same ViewModel. Be mindful here in what order you execute things.

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
            }
        });
    }
}

这篇关于架构FragmentStatePagerAdapter,ViewModel和一个Fragment列表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆