Android fragments 片段在删除+;添加
我目前正在研究Android fragments 片段在删除+;添加,android-fragments,android-viewmodel,android-livedata,mutablelivedata,Android Fragments,Android Viewmodel,Android Livedata,Mutablelivedata,我目前正在研究片段的生命周期与ViewModel和LiveData的关系 我有两个片段,片段a和片段b。 我在每个片段的onCreate方法中添加Observer @Override public void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); sharedViewModel = ViewModelProviders.of(getActivity())
片段的生命周期与ViewModel
和LiveData
的关系
我有两个片段
,片段a
和片段b
。
我在每个片段的onCreate
方法中添加Observer
@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);
}
});
}
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;
}
}
Replace
导致片段
被完全销毁,并在下次添加时再次运行其onCreate
方法。我可以确认为屏幕上放置的每个片段
调用了onCreate
,并且添加了观察者
。
但是一旦我替换了片段并重新添加它,它就完全停止了onChanged
中的任何更新。甚至是它自己发送的那些onChanged
不再触发。我不明白为什么
编辑:
事实上,我发现if
在LiveData
类中的检查返回了第二次,我尝试添加观察者
(在第一次替换片段之后):
@MainThread
公共无效观察(@NonNull LifecycleOwner owner,@NonNull Observer根据:
在此事件之后,此生命周期将不再调度任何事件
也就是说,销毁
是一种终端状态,一旦销毁,该生命周期将始终被销毁
这意味着有两种正确的方法来做你想做的事情:
每次调用switchToA
或switchToB
时,都要创建一个新的片段实例。由于删除片段时所有状态都会被破坏,因此重用片段实例不会获得任何好处
不要使用replace
,而是使用attach()
和detach()
(即,附加要显示的片段,分离要隐藏的片段)。片段在分离时保持其状态(它们不会被销毁),因此重新附加它会将其移回恢复状态
谢谢。所以我想对于ViewModel来说,再也没有必要重用被删除的片段实例了,因为我们用最新的数据更新了新的实例?当您销毁片段时,它的ViewModel也会被销毁,所以这当然是选项1的一个缺点。如果您使用选项1,它可能对这些更有意义要成为在片段被销毁时不会被销毁的活动范围的ViewModels,我实际上在问题中使用了一个活动范围的ViewModel。但是一旦片段通过onDestroy,我们总是必须创建一个新实例,就像你在1中解释的那样。
,对吗?啊,错过了你使用的是活动范围的ViewModel。在在这种情况下,是的,选项1可以很好地工作。但是这是一个bug吗?我觉得如果片段再次创建,它的生命周期应该“复活”
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;
}
}
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();
}
}
@MainThread
public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) {
assertMainThread("observe");
if (owner.getLifecycle().getCurrentState() == DESTROYED) {
// ignore
return;
}