我正在使用 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 许可协议
这里的问题是,当您从活动中分离片段时,片段及其视图模型都不会被破坏。当你回来时,你添加一个新的观察者到
livedata
而旧的观察者还在同一个片段中(如果你添加观察者在onCreateView()
)。有 一篇文章(实际上甚至是一个 SO 线程)在谈论它(带有解决方案)。修复它的简单方法(也在文章中)是在添加观察者之前从实时数据中删除任何观察者。
更新:在支持库 v28 中,一个名为 ViewLifeCycleOwner 的新 LifeCycleOwner 应该在 此处 修复更多信息