从 Fragment 返回时,ViewModel onchange 被多次调用

新手上路,请多包涵

我正在使用 Android 架构组件。我想要的是当用户在 Edittext 中键入“0”并单击 Button 以用新 Fragment 替换 Fragment 时,如果键入任何其他内容,则发布 Toast 错误消息。问题是,当我从新的 Fragment(BlankFragment) 返回并再次单击按钮并再次键入“0”并单击时, onchange() 被多次调用,因此多次创建片段

片段示例类:

      @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        manager = getActivity().getSupportFragmentManager();
        viewmModel = ViewModelProviders.of(getActivity(), viewModelFactory)
                .get(VModel.class);

        View v = inflater.inflate(R.layout.fragment_list, container, false);
        b = (Button) v.findViewById(R.id.b);
        et = (EditText) v.findViewById(R.id.et);

        viewmModel.observeData().observe(getActivity(), new Observer<String>() {
            @Override
            public void onChanged(@Nullable String s) {

                if(s.equals("0")) {
                    BlankFragment fragment = (BlankFragment) manager.findFragmentByTag(DETAIL_FRAG);
                    if (fragment == null) {
                        fragment = BlankFragment.newInstance();
                    }
                    addFragmentToActivity(manager,
                            fragment,
                            R.id.root_activity_detail,
                            DETAIL_FRAG
                    );
                } else {
                    Toast.makeText(getContext(), "Wrong text", Toast.LENGTH_SHORT).show();
                }
            }
        });

        b.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                viewmModel.setData(et.getText().toString());
            }
        });
        return v;
    }
    private void addFragmentToActivity(FragmentManager fragmentManager, BlankFragment fragment, int root_activity_detail, String detailFrag) {
        android.support.v4.app.FragmentTransaction transaction = fragmentManager.beginTransaction();
        transaction.replace(root_activity_detail, fragment, detailFrag).addToBackStack(detailFrag);
        transaction.commit();
    }

存储库类:


    public class Repository {
    MutableLiveData<String> dataLive = new MutableLiveData<>();

    public Repository() {

    }

    public void setListData(String data) {
       dataLive.setValue(data);
    }

    public MutableLiveData<String> getData() {
        return dataLive;
    }
}

空白片段类:

     @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {

        listItemViewModel = ViewModelProviders.of(this, viewModelFactory)
                .get(VModel.class);
        listItemViewModel.setData("");
        return inflater.inflate(R.layout.fragment_blank, container, false);
    }

原文由 Nikolas Bozic 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 704
2 个回答

这里的问题是,当您从活动中分离片段时,片段及其视图模型都不会被破坏。当你回来时,你添加一个新的观察者到 livedata 而旧的观察者还在同一个片段中(如果你添加观察者在 onCreateView() )。有 一篇文章(实际上甚至是一个 SO 线程)在谈论它(带有解决方案)。

修复它的简单方法(也在文章中)是在添加观察者之前从实时数据中删除任何观察者。

更新:在支持库 v28 中,一个名为 ViewLifeCycleOwner 的新 LifeCycleOwner 应该在 此处 修复更多信息

原文由 Julien Neo 发布,翻译遵循 CC BY-SA 4.0 许可协议

这是我如何解决这个问题的例子。 [测试和工作]

  viewModel.getLoginResponse().observe(getViewLifecycleOwner(), new Observer<String>() {
        @Override
        public void onChanged(String response) {
            if(getViewLifecycleOwner().getLifecycle().getCurrentState()== Lifecycle.State.RESUMED){
                // your code here ...
            }

        }
    });

原文由 Biplob Das 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题