如何生成带有临时子视图的组合视图模型? [英] How to generate composed view models with temporary sub views?

查看:95
本文介绍了如何生成带有临时子视图的组合视图模型?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个测验生成器,它生成一系列不同类别的测验.序列的长度是无限的.

I have a quizz generator, which generates a sequence of quizzes of different classes. The sequence is of unlimited length.

有一个测验生成器的视图模型.每种测验都有一个视图模型.测验生成器视图模型应根据测验的类创建测验的视图模型.

There is a view model for the quizz generator. There is a view model for each type of a quizz. The quizz generator view model should create the view models of the quizzes depending on their classes.

视图模型不能包含对生命周期的引用,但是我需要生命周期来创建视图模型.

A view model must not hold a reference to the lifecycle, but I need the lifecycle to create view models.

ViewModelProviders.of(lifecycle).get(classForQuizzType);

问题

我在哪里创建测验的子视图模型?

Questions

Where do I create the sub view models of the quizzes?

我能想到的一个解决方案是每次从活动中注入子视图模型.这是绕道而行的,特别是在涉及嵌套视图的情况下.

The one solution I can think of is to inject the sub view model from the activity each time. This is a detour, especially if nested views are involved.

另一种解决方案是在嵌套视图中创建视图模型,这看起来也很丑陋,因为从视图内部访问生命周期并不常见.

The other solution is to create the view model in the nested view, which seems ugly either, as it is not common practice to access the lifecycle from inside a view.

如果没有干净的解决方案,那么我的体系结构方法有什么问题?在这种情况下我应该使用片段吗?

If there is no clean solution, what's wrong with my approach of architecture? Should I use fragments for this kind of scenario?

推荐答案

如果没有干净的解决方案,我的处理方法有什么问题 建筑学?在这种情况下我应该使用片段吗?

If there is no clean solution, what's wrong with my approach of architecture? Should I use fragments for this kind of scenario?

是的,片段是正确的选择

摘要:

  1. 通过LiveData绑定Views并没有真正的选择.
  2. 如果使用LiveData,则需要LifeCycle.
  3. 如果序列中子视图的生命周期应该短于活动的生命周期,那么片段就是要走的路.
  1. There is no real alternative to binding Views by LiveData.
  2. If using LiveData a LifeCycle is required.
  3. If the lifecycle of a sub views in a sequence should be shorter than the lifecycle of the activity, then fragments are the way to go.

详细信息

通过LiveData绑定Views并没有真正的选择.

视图模型不应保存对视图的无终止引用,否则只要存在视图模型而导致内存泄漏,视图就存在.共有三种观察者模式来讨论视图如何观察视图模型.

Details

There is no real alternative to binding Views by LiveData.

View models should not hold unterminated references to views, else the views exists as long as the view model exists causing memory leaks. There are three observer patterns to discuss how views could observe view models.

a.)MutableLiveData

a.) MutableLiveData

它们需要生命周期.生命周期结束时,引用将自动清除.这是推荐的解决方案.

They require a lifecycle. The references are cleaned up automatically, when the lifecycle ends. This is the recommended solution.

b.)弱引用

从理论上讲,这应该可行.当对视图的最后一个硬引用消失时,应由垃圾收集器清理弱引用.实际上,该解决方案是不稳定的,并且引用有时会过早消失.

In theory this should work. The weak reference should be cleaned up by the garbage collector, when the last hard reference to the view is gone. In practice the solution is unstable and references sometime go away prematurely.

c.)手工观察者

手工观察者必须调用remove方法.不幸的是,当视图消失时,没有定义的销毁钩子.在视图中没有地方可以调用remove方法.

A handmade observer must call a remove method. Unfortunately there is no defined destruction hook, when a view goes away. There is no place to call the remove method in a view.

因此,根据我的经验,a.)是唯一可能的解决方案.

As a result a.) is the only possible solution according to my experience.

此处提到的子视图是按顺序创建的.如果我们将它们绑定到活动上,它们将堆积直到活动消失,尽管按顺序只需要一小段时间即可.

The sub views mentioned here are created in a sequence. If we would bind them to the activity, they would pile up until the activity goes away although they are only needed for a small interval of time in sequence.

碎片可以在活动的一部分时间内存在.它们是将序列的子视图绑定到它们的正确解决方案.

Fragments can exist for a subpart of the time of the activity. They are the right solution to bind the sub views of the sequence to them.

测验在这里被称为挑战. FragmentManger始终是活动的内容,而LifecycleOwner是活动或片段的内容.

The quizzes are called challenges here. The FragmentManger is always that of the activity, while the LifecycleOwner is either the activity or a fragment.

# A view model acceptor interface for views

public interface ViewModelAcceptor<T extends  ViewModel> {
    void plugViewModel(
        T viewModel,
        LifecycleOwner lifecycleOwner,
        FragmentManager fragmentManager
    );
}

# In the parent view class of the challenges new challenges are created
# in sequence

ChallengeFragment challengeFragment = new ChallengeFragment();
challengeFragment.setChallengeViewModel(challengeViewModel);
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(this.getId(), challengeFragment);
fragmentTransaction.commit();

# ChallengeFragment

public class ChallengeFragment extends Fragment {

    private ChallengeViewModel challengeViewModel;

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState) {
        return new ChallengeView(getActivity(), null);
    }

    public void setChallengeViewModel(ChallengeViewModel challengeViewModel) {
        this.challengeViewModel = challengeViewModel;
    }

    @Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        ChallengeView challengeView = (ChallengeView) getView();
        Objects.requireNonNull(challengeView)
                .plugViewModel(challengeViewModel, this, getFragmentManager());
    }

}
# Challenge views are the child views of the sequence

public class ChallengeView extends ConstraintLayout implements ViewModelAcceptor<ChallengeViewModel> {
  [...]
}

这篇关于如何生成带有临时子视图的组合视图模型?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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