从Fragment返回时,多次调用ViewModel onchange [英] ViewModel onchange gets called multiple times when back from Fragment
问题描述
我正在使用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屋!