Flo*_*her 3 android-fragments android-livedata android-viewmodel mutablelivedata
我目前正在玩弄fragment与ViewModel和相关的生命周期的窍门LiveData。
我有 2 fragments,fragmentA和fragmentB. 我Observer在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);
}
});
}
Run Code Online (Sandbox Code Playgroud)
每个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());
}
});
[...]
}
Run Code Online (Sandbox Code Playgroud)
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;
}
}
Run Code Online (Sandbox Code Playgroud)
当我单击一个按钮时,我会替换另一个按钮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();
}
}
Run Code Online (Sandbox Code Playgroud)
Replace导致fragment完全销毁并onCreate在下次添加时再次运行它的方法。我可以确认onCreate为每个fragment放置在屏幕上的调用调用并Observer添加了。但是一旦我替换了 afragment并重新添加了它,它就完全停止在onChanged. 即使是它自己发送的那些。onChanged只是不再触发。我不明白为什么。
编辑:
我实际上发现类中的 followigif检查LiveData返回第二次我尝试添加Observer(在替换fragment第一个之后):
@MainThread
public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) {
assertMainThread("observe");
if (owner.getLifecycle().getCurrentState() == DESTROYED) {
// ignore
return;
}
Run Code Online (Sandbox Code Playgroud)
因此,Observer不再添加。为什么当我尝试重新添加时getCurrentState()返回?DESTROYEDfragment
简而言之:Observer删除时fragment删除 ,但Observer下次添加片段时不会添加另一个。
根据Lifecycle.State.DESTROYED 文档:
在此事件之后,此 Lifecycle 将不再调度任何事件。
即,DESTROYED是一个终止状态,一旦它被销毁,该 Lifecycle 将始终被销毁。
这意味着有两种正确的方法可以做你想做的事:
每次调用switchToA或时都会创建一个新的 Fragment 实例switchToB。由于移除 Fragment 时所有状态都会被销毁,因此通过重用 Fragment 实例不会获得任何收益。
不要使用replace,而是使用attach()和detach()(即,附加您要显示的那个,分离您要隐藏的那个)。碎片在分离时保持其状态(它们不会被销毁),因此重新附加它会将其移回恢复状态。
| 归档时间: |
|
| 查看次数: |
1414 次 |
| 最近记录: |