从 Fragment 返回时,多次调用 ViewModel onchange [英] ViewModel onchange gets called multiple times when back from Fragment

查看:47
本文介绍了从 Fragment 返回时,多次调用 ViewModel onchange的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am working with Android architecture components. What i want is when user type "0" in Edittext and click on Button to replace Fragment with new one , and if type anything else post Toast error message. In Problem is when i back from new Fragment(BlankFragment) and click on button again and type "0" again and click, onchange() is called multiple times so Fragment is get created multiple times

FragmentExample.class:

FragmentExample.class:

     @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;
    }
}

BlankFragment.class:

BlankFragment.class:

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

推荐答案

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

The problem here is that when you dettach the fragment from the acitivity, both fragment and its viewmodel are not destroyed. When you come back, you add a new observer to the livedata when the old observer is still there in the same fragment (If you add the observer in onCreateView()). There is an article (Even a SO thread in fact) talking about it (with solution).

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

The easy way to fix it (also in the article) is that remove any observer from the livedata before you add observer to it.

更新:在支持库 v28 中,名为 ViewLifeCycleOwner 的新 LifeCycleOwner 应该修复 中的更多信息这里

Update: In the support lib v28, a new LifeCycleOwner called ViewLifeCycleOwner should fix that more info in here

这篇关于从 Fragment 返回时,多次调用 ViewModel onchange的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆