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

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

问题描述

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

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天全站免登陆