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将在旋转/配置更改期间(部分)保留
我看到了以下场景:
.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
});
}
}