Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/139.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 支持片段管理器.replace()和ViewModel_Android_Android Architecture Components - Fatal编程技术网

Android 支持片段管理器.replace()和ViewModel

Android 支持片段管理器.replace()和ViewModel,android,android-architecture-components,Android,Android Architecture Components,无论何时,只要在带有支持片段管理器的事务中使用.replace()方法,就会重新创建ViewModel。这是故意的吗?片段实例本身没有更改,并且ViewModel将在旋转/配置更改期间(部分)保留 我看到了以下场景: 获取视图模型引用(计数=0),更新计数=1,旋转,计数=1,再次调用onCreate,计数=0(重新创建视图模型) 调用.replace()并重新创建视图模型(活动和片段实例保持不变) 使用支持库26.0.0 正在my fragment的onCreate中创建ViewModel,其

无论何时,只要在带有支持片段管理器的事务中使用
.replace()
方法,就会重新创建ViewModel。这是故意的吗?片段实例本身没有更改,并且ViewModel将在旋转/配置更改期间(部分)保留

我看到了以下场景:

  • 获取视图模型引用(计数=0),更新计数=1,旋转,计数=1,再次调用onCreate,计数=0(重新创建视图模型)
  • 调用
    .replace()
    并重新创建视图模型(活动和片段实例保持不变) 使用支持库26.0.0

    正在my fragment的
    onCreate
    中创建
    ViewModel
    ,其范围为
    fragment

    viewModel = ViewModelProviders.of(this).get(DashboardViewModel::class.java)
    
    有没有人能解释一下这是否正常?

    replace()
    支持在生成不同片段时调用。对于您调用的相同片段
    update()

    replace()
    方法意味着您可以用具有不同布局(物理结构)的不同片段替换当前片段。你甚至不能保证它是从上一个片段使用的相同内存开始的
    ViewModel
    是一种针对整个容器的布局。因此,对于具有不同物理结构和内存的对象(可能具有不同的内存--我正在编写可能,因为您也可以用相同的片段替换),您必须重新创建不同的
    ViewModel
    ,以定义其容器。这是因为一个
    ViewModel
    对象指向一个引用容器,下一次您有不同的片段时,您的片段容器由ViewModel在其他地方定义,因此您需要另一个
    ViewModel
    对象指向该片段容器

    但是当您执行
    update()
    rotate()
    时,您可以保证更新片段的内存空间可以减少/增加,但它的启动内存仍然保持不变。因此无需创建
    ViewModel
    。这是因为旧的
    ViewModel
    对象正在引用同一个旧片段的容器

    当您执行create()时,它会创建GUI所有内容,因此,很明显,会再次发生
    ViewModel
    创建

    ViewModel
    count
    的跟踪基于上述解释

    ViewModel是在onCreate of my fragment中创建的,其作用域为该片段。这是对片段的一种权力委托。

    replace()
    支持在创建不同片段时调用。对于您调用的相同片段
    update()

    replace()
    方法意味着您可以用具有不同布局(物理结构)的不同片段替换当前片段。你甚至不能保证它是从上一个片段使用的相同内存开始的
    ViewModel
    是一种针对整个容器的布局。因此,对于具有不同物理结构和内存的对象(可能具有不同的内存--我正在编写可能,因为您也可以用相同的片段替换),您必须重新创建不同的
    ViewModel
    ,以定义其容器。这是因为一个
    ViewModel
    对象指向一个引用容器,下一次您有不同的片段时,您的片段容器由ViewModel在其他地方定义,因此您需要另一个
    ViewModel
    对象指向该片段容器

    但是当您执行
    update()
    rotate()
    时,您可以保证更新片段的内存空间可以减少/增加,但它的启动内存仍然保持不变。因此无需创建
    ViewModel
    。这是因为旧的
    ViewModel
    对象正在引用同一个旧片段的容器

    当您执行create()时,它会创建GUI所有内容,因此,很明显,会再次发生
    ViewModel
    创建

    ViewModel
    count
    的跟踪基于上述解释


    ViewModel是在onCreate of my fragment中创建的,其作用域为该片段。这是对片段的一种权力委托。

    正如@commonware所提到的,
    fragment
    中的
    viewmodel
    实例在
    活动中应该是相同的

    因此,在活动中,您应该这样做

    MyViewModel vm=ViewModelProviders.of(this.get)(MyViewModel.class)

    在片段内部,您应该执行以下操作

    MyViewModel vm=ViewModelProviders.of(getActivity()).get(MyViewModel.class)

    结果,它们将使用相同的实例

    但是,如果您试图在片段内部使用它

    MyViewModel vm=ViewModelProviders.of(this.get)(MyViewModel.class)

    旋转设备时,将在片段中重新创建Viewmodel由于实例保存在片段中而不是活动中,因此在重新创建活动时,片段和MyViewModel实例也将重新创建。

    试着看一看关于主细节片段的示例(这可能很容易解决您的问题)

    我还在github上制作了简单的主细节模板


    正如@commonware所提到的,
    片段中的
    viewmodel
    实例在
    活动中应该是相同的

    因此,在活动中,您应该这样做

    MyViewModel vm=ViewModelProviders.of(this.get)(MyViewModel.class)

    在片段内部,您应该执行以下操作

    MyViewModel vm=ViewModelProviders.of(getActivity()).get(MyViewModel.class)

    结果,第
    public class MasterFragment extends Fragment {
        private SharedViewModel model;
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            model = ViewModelProviders.of(getActivity()).get(SharedViewModel.class);
            itemSelector.setOnClickListener(item -> {
                model.select(item);
            });
        }
    }
    
    public class DetailFragment extends LifecycleFragment {
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            SharedViewModel model = ViewModelProviders.of(getActivity()).get(SharedViewModel.class);
            model.getSelected().observe(this, { item ->
               // update UI
            });
        }
    }