我有两个片段的简单设置:ConversationFragment
和DetailsFragment
我正在使用Room
并Paging 3 library
填充ConversationFragment
我正在使用的PagingLiveData
实现以及AndroidViewModel
属于ConversationFragment
.
我没有使用Navigation Components
这里,只是根据 Android 文档的常见片段导航。
从那个片段我可以打开DetailsFragment
然后再次返回片段。一切都运行良好,直到我打开所述片段并返回,然后绑定在 中的观察者ConversationFragment
丢失,因为在打开DetailsFragment
.
到目前为止,这不是一个大问题,我可以再次重新启动观察者,并且当我这样做时它确实有效。但是,当我再次附加观察者时,整个列表重排,这会导致列表中的项目RecyclerView
变得疯狂,列表所在的位置丢失并且滚动条改变大小,确认页面正在加载/重新加载。
我可以在一定程度上承受这种奇怪的行为,但在此之上失去位置是不可接受的。
我研究了在视图模型中缓存结果,但我可以在可用文档中找到的示例是基本的,并没有显示如何使用LiveData<PagingData<...>
对象实现相同的目标。
目前这就是我所拥有的:
ConversationFragment
@Override
public void onViewCreated(
@NonNull View view,
@Nullable Bundle savedInstanceState
) {
if (viewModel == null) {
viewModel = new ViewModelProvider(this).get(ConversationViewModel.class);
}
if (savedInstanceState == null) {
// adapter is initialized in onCreateView
viewModel
.getList(getViewLifecycleOwner())
.observe(getViewLifecycleOwner(), pagingData -> adapter.submitData(lifecycleOwner.getLifecycle(), pagingData));
}
super.onViewCreated(view, savedInstanceState);
}
ConversationViewModel
public class ConversationViewModel extends AndroidViewModel {
final PagingConfig pagingConfig = new PagingConfig(10, 10, false, 20);
private final Repository repository;
private final MutableLiveData<PagingData<ItemView>> messageList;
public ConversationFragmentVM(@NonNull Application application) {
super(application);
messageList = new MutableLiveData<>();
repository = new Repository(application);
}
public LiveData<PagingData<ItemView>> getList(@NonNull LifecycleOwner lifecycleOwner) {
// at first I tried only setting the value if it was null
// but since the observer is lost on destroy and the value
// is not it would never be able to "restart" the observer
// again
// if (messageList.getValue() == null) {
PagingLiveData.cachedIn(
PagingLiveData.getLiveData(new Pager<>(pagingConfig, () -> repository.getMessageList())),
lifecycleOwner.getLifecycle()
).observe(lifecycleOwner, messageList::setValue);
// }
return messageList;
}
}
事实上,即使我返回PagingLiveData.cachedIn
片段时的行为结果也是一样的;这些项目在 recyclerview 列表中显示出不稳定的行为,并且它所在的位置完全丢失了。
这是此处提供的代码实验室:https ://developer.android.com/codelabs/android-training-livedata-viewmodel#8
正如您所看到的mAllWords
,它们被缓存并且它们仅在第一次构造视图模型时才被初始化,任何后续更改都只是更新,并且只需要在片段被销毁并再次创建时附加新的观察者而仍在回栈。
这就是我想要做的,但它并没有像我想象的那样工作,至少它不像我想象的那么简单。
如何做到这一点?