Android ViewModel 无法在片段更改后继续存在
Android ViewModel doesn't survive fragment change
我一直在尝试使用视图模型和实时数据在片段之间共享信息。
但是,当我从第一个片段更改为另一个片段时,我的视图模型似乎已重新初始化,这让我丢失了之前存储的所有数据。
我在我的片段中以相同的方式获得了两次我的视图模型:
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
interventionViewModel = ViewModelProviders.of(this).get(InterventionsViewModel.class);
}
这就是我在 activity 中替换 framgents 的方式(我想问题一定来自片段生命周期,但我不知道错误在哪里 :/)
public void showFragment(Fragment fragment) {
String TAG = fragment.getClass().getSimpleName();
FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.fragment_container, fragment, TAG);
fragmentTransaction.addToBackStack(null);
fragmentTransaction.commitAllowingStateLoss();
}
public void backstackFragment() {
Log.d("Stack count", getSupportFragmentManager().getBackStackEntryCount() + "");
if (getSupportFragmentManager().getBackStackEntryCount() == 0) {
finish();
}
getSupportFragmentManager().popBackStack();
removeCurrentFragment();
}
private void removeCurrentFragment() {
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
Fragment currentFrag = getSupportFragmentManager()
.findFragmentById(R.id.fragment_container);
if (currentFrag != null) {
transaction.remove(currentFrag);
}
transaction.commitAllowingStateLoss();
}
当我需要一个片段时,我调用 backStackFragment()
来删除当前片段,然后我调用 showFragment(MyFragment.newInstance());
片段是AndroidStudio生成的片段
感谢您的帮助,
诚挚地,
马修
尝试绑定到 activity 而不是当前片段。
interventionViewModel = ViewModelProviders.of(activity).get(InterventionsViewModel.class);
call getActivity()
片段中的方法 return activity
viewModel = ViewModelProviders.of(getActivity()).get(MyViewModel.class);
我认为你应该用 onActivityCreated
方法初始化你的视图模型而不是像这样 onCreate
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
interventionViewModel = ViewModelProviders.of(this).get(InterventionsViewModel.class);
}
它仍然很奇怪,当片段变化太大(2 步或更多步)时它会保持重新加载,但它仍然有效,我更喜欢使用 androidx.loader.content.AsyncTaskLoader
,加载器可以很好地保存你的数据。
因为 ViewModelProviders
class is deprecated 正确的方法是使用 ViewModelProvider
并通过使用
将 ViewModel 绑定到活动生命周期来让 ViewModel 在片段生命周期中存活下来
requireActivity()
如 Google here 所述:
model = new ViewModelProvider(requireActivity()).get(SharedViewModel.class);
我一直在尝试使用视图模型和实时数据在片段之间共享信息。
但是,当我从第一个片段更改为另一个片段时,我的视图模型似乎已重新初始化,这让我丢失了之前存储的所有数据。
我在我的片段中以相同的方式获得了两次我的视图模型:
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
interventionViewModel = ViewModelProviders.of(this).get(InterventionsViewModel.class);
}
这就是我在 activity 中替换 framgents 的方式(我想问题一定来自片段生命周期,但我不知道错误在哪里 :/)
public void showFragment(Fragment fragment) {
String TAG = fragment.getClass().getSimpleName();
FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.fragment_container, fragment, TAG);
fragmentTransaction.addToBackStack(null);
fragmentTransaction.commitAllowingStateLoss();
}
public void backstackFragment() {
Log.d("Stack count", getSupportFragmentManager().getBackStackEntryCount() + "");
if (getSupportFragmentManager().getBackStackEntryCount() == 0) {
finish();
}
getSupportFragmentManager().popBackStack();
removeCurrentFragment();
}
private void removeCurrentFragment() {
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
Fragment currentFrag = getSupportFragmentManager()
.findFragmentById(R.id.fragment_container);
if (currentFrag != null) {
transaction.remove(currentFrag);
}
transaction.commitAllowingStateLoss();
}
当我需要一个片段时,我调用 backStackFragment()
来删除当前片段,然后我调用 showFragment(MyFragment.newInstance());
片段是AndroidStudio生成的片段
感谢您的帮助,
诚挚地, 马修
尝试绑定到 activity 而不是当前片段。
interventionViewModel = ViewModelProviders.of(activity).get(InterventionsViewModel.class);
call getActivity()
片段中的方法 return activity
viewModel = ViewModelProviders.of(getActivity()).get(MyViewModel.class);
我认为你应该用 onActivityCreated
方法初始化你的视图模型而不是像这样 onCreate
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
interventionViewModel = ViewModelProviders.of(this).get(InterventionsViewModel.class);
}
它仍然很奇怪,当片段变化太大(2 步或更多步)时它会保持重新加载,但它仍然有效,我更喜欢使用 androidx.loader.content.AsyncTaskLoader
,加载器可以很好地保存你的数据。
因为 ViewModelProviders
class is deprecated 正确的方法是使用 ViewModelProvider
并通过使用
requireActivity()
如 Google here 所述:
model = new ViewModelProvider(requireActivity()).get(SharedViewModel.class);