看来每当您在支持片段管理器的事务中使用.replace()
方法时,都会重新创建ViewModel。这是故意的吗? Fragment实例本身不会更改,并且在旋转/配置更改期间将(部分)保留ViewModel。
我看到以下情况:
.replace()
并重新创建视图模型(活动和片段实例不变)。 使用支持库26.0.0。
我的片段的ViewModel
正在创建onCreate
,其范围限定为Fragment
:
viewModel = ViewModelProviders.of(this).get(DashboardViewModel::class.java)
如果这是正常的话,有人会说清楚吗?
答案 0 :(得分:2)
正如@CommonsWare所提到的,viewmodel
中的fragment
实例在Activity
中应该是相同的。
因此,在Activity中,你应该做这样的事情
MyViewModel vm = ViewModelProviders.of(this).get(MyViewModel.class);
在Fragment中,你应该做这样的事情
MyViewModel vm = ViewModelProviders.of(getActivity()).get(MyViewModel.class);
结果,他们将使用相同的实例。
但是,如果您尝试在片段
中使用它 MyViewModel vm = ViewModelProviders.of(this).get(MyViewModel.class);
旋转设备时,将在片段中重新创建Viewmodel。 由于实例保留在片段内而不是活动中,因此当重新创建活动时,片段也将被重新创建,并且MyViewModel实例将被重新创建。
尝试查看主详细信息片段上的示例(可能很容易解决您的问题)ViewModel in Android Developer
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
});
}
}
我还在github上制作了简单的Master Detail模板
答案 1 :(得分:1)
replace()
被调用。对于相同的片段,请调用update()
。
replace()
方法意味着您可以用不同的片段替换当前的片段,片段具有不同的布局(物理结构)。您甚至无法保证它从前一个片段使用的内存开始。 ViewModel
是整个容器的布局。因此,对于具有不同物理结构的对象(可能具有不同的内存 - 我正在写可能因为您也可以用相同的片段替换),您必须重新创建不同的ViewModel
到定义它的容器。这是因为一个ViewModel
对象指向一个引用Container,下次有不同的片段时,ViewModel定义的片段容器位于其他位置,因此您需要另一个ViewModel
对象来指向Fragment Container。
但是当你执行update()
或rotate()
时,你可以保证更新后的片段的内存空间可以减少/增加,但它的启动内存仍然保持不变。因此无需创建ViewModel
。这是因为您的旧ViewModel
对象引用了相同的旧Fragment容器。
当你执行create()时,它会创建GUI所有内容,因此,显然会再次创建ViewModel
。
ViewModel
count
的跟踪基于以上说明。
ViewModel正在my片段的onCreate中创建,并且作用于Fragment。这是片段的权力授权。