我目前正在四处寻找与fragment
和ViewModel
相关的LiveData
生命周期。
我有2个fragments
,fragmentA
和fragmentB
。
我在每个Observer
的{{1}}方法中添加onCreate
。
fragment
每个@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
sharedViewModel = ViewModelProviders.of(getActivity()).get(SharedViewModel.class);
sharedViewModel.getText().observe(this, new Observer<CharSequence>() {
@Override
public void onChanged(CharSequence charSequence) {
editText.setText(charSequence);
}
});
}
都有一个按钮,用于更改共享的fragment
中的LiveData
ViewModel
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
[...]
buttonOk.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
sharedViewModel.setText(editText.getText());
}
});
[...]
}
:
SharedViewModel
单击按钮时,我将public class SharedViewModel extends ViewModel {
private MutableLiveData<CharSequence> text = new MutableLiveData<>();
public void setText(CharSequence input) {
text.setValue(input);
}
public LiveData<CharSequence> getText() {
return text;
}
}
替换为另一个。
fragment
public class MainActivity extends AppCompatActivity {
Fragment fragmentA = new FragmentA();
Fragment fragmentB = new FragmentB();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (savedInstanceState == null) {
getSupportFragmentManager().beginTransaction()
.add(R.id.container_a, fragmentA)
.commit();
}
}
public void switchToA(View v) {
getSupportFragmentManager().beginTransaction()
.replace(R.id.container, fragmentA)
.commit();
}
public void switchToB(View v) {
getSupportFragmentManager().beginTransaction()
.replace(R.id.container, fragmentB)
.commit();
}
}
导致Replace
被完全销毁并在下一次添加时再次通过其fragment
方法运行。我可以确认为放置在屏幕上的每个onCreate
都调用了onCreate
,并且添加了fragment
。
但是,一旦我替换了Observer
并重新添加了它,它就会完全停止获取fragment
中的任何更新。甚至它发送的那些。 onChanged
不再被触发。我不明白为什么。
编辑:
我实际上发现onChanged
类中的followig if
检查返回了第2次,我尝试添加LiveData
(在替换{ {1}}(第一个):
Observer
因此,fragment
不再添加。为什么在我尝试重新添加@MainThread
public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) {
assertMainThread("observe");
if (owner.getLifecycle().getCurrentState() == DESTROYED) {
// ignore
return;
}
时Observer
返回getCurrentState()
?
简而言之:DESTROYED
被删除时,fragment
被删除了,但是下次添加该片段时,它不会再添加另一个Observer
。
答案 0 :(得分:4)
按照Lifecycle.State.DESTROYED documentation:
此事件之后,此生命周期将不再调度任何事件。
即DESTROYED
是终端状态,一旦销毁,生命周期将始终被销毁。
这意味着有两种正确的方法可以完成您想要的事情:
switchToA
或switchToB
时,创建一个新的Fragment实例。由于删除Fragment时所有状态都被破坏,因此重用Fragment实例不会获得任何收益。
不要使用replace
,而要使用attach()
和detach()
(即,附加要显示的内容,分离要隐藏的内容)。碎片在分离时仍保持其状态(不会被破坏),因此重新附加碎片会将其移回恢复状态。