Android ViewModel在fragment更改时无法存活。

8

我一直在尝试使用ViewModel和LiveData在Fragment之间共享信息。

但是,当我从一个片段切换到另一个片段时,我的ViewModel貌似被重新初始化了,导致我失去了所有先前存储的数据。

我在我的片段中以相同的方式获取我的ViewModel:

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    interventionViewModel = ViewModelProviders.of(this).get(InterventionsViewModel.class);

}

这是我在活动中替换片段的方法(我猜问题一定来自片段的生命周期,但我无法确定错误出在哪里:/)

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();
}

当我需要一个fragment时,我会调用backStackFragment()来移除当前的fragment然后调用showFragment(MyFragment.newInstance()); 这些fragments是由AndroidStudio生成的。
感谢您的帮助,
诚挚地, Matthieu
4个回答

13

尝试将绑定对象更改为当前活动而不是片段。

interventionViewModel = ViewModelProviders.of(activity).get(InterventionsViewModel.class);

观察者也需要吗?(顺便说一句,回答好快哦 :o) - Matthieu Meunier
当然可以!! :) - Algar
谢谢,它起作用了!你比stackoverflow快得多,当它允许我接受你的答案时,我会接受它...我很愚蠢,绑定活动感觉更有逻辑...再次感谢! - Matthieu Meunier
我很感激 :) - Algar
为什么你必须使用一个Activity?难道ViewModel的整个意义不就是它可以在元素被销毁(如片段)时幸存下来吗? - spiff
@spiff:是的,你说得对!但如果你想要一个SharedViewModel,那么你需要传递活动的上下文。 - Astha Garg


0
在编程中,可以在片段中调用call getActivity() 方法以返回活动。
viewModel = ViewModelProviders.of(getActivity()).get(MyViewModel.class);

-1

我认为你应该在onActivityCreated方法中初始化你的视图模型,而不是像这样在onCreate

@Override
public void onActivityCreated(Bundle savedInstanceState) {
    super.onActivityCreated(savedInstanceState);
    interventionViewModel = ViewModelProviders.of(this).get(InterventionsViewModel.class);

}

还是有点奇怪,当片段改变相对较远(2个或更多步骤)时,它会重载,但它确实有效,我更喜欢使用 androidx.loader.content.AsyncTaskLoader,该加载器可以非常好地保存您的数据。


不需要在onCreateView中使用onActivityCreated,而且加载器已经过时了。 - EpicPandaForce
以上的回答对我都不起作用,所以我想出了这个...你能提供更好的答案吗? - Augustine Sena

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接