В конечном итоге я смог это исправить, наблюдая за games
LiveData. Однако это было не совсем просто.
Вот мой класс DatabaseState:
sealed class DatabaseState {
object Success : DatabaseState()
object LoadingSortChange: DatabaseState()
object Loading: DatabaseState()
}
Захватить состояние загрузки было легко. Всякий раз, когда пользователь обновляет параметры сортировки, я вызываю метод, подобный этому:
fun updateSortOptions(newSortOptions: SortOptions) {
_databaseState.value = DatabaseState.LoadingSortChange
_sortOptions.value = newSortOptions
}
Состояние успеха было сложным. Поскольку мои параметры сортировки содержатся в отдельном фрагменте от RecyclerView, наблюдатель games
LiveData запускается дважды при сохранении новых параметров сортировки (один раз при возобновлении ListFragment, а затем снова немного позже после завершения запроса к базе данных). Поэтому мне пришлось учесть это следующим образом:
/**
* The observer that triggers this method fires once under normal circumstances, but fires
* twice if the sort options change. When sort options change, the "success" state doesn't occur
* until the second firing. So in this case, DatabaseState transitions from LoadingSortChange to
* Loading, and finally to Success.
*/
fun updateDatabaseState() {
when (databaseState.value) {
Database.LoadingSortChange -> gameRepository.updateDatabaseState(DatabaseState.Loading)
DatabaseState.Loading -> gameRepository.updateDatabaseState(DatabaseState.Success)
}
}
Наконец, мне нужно было внести некоторые изменения в мой BindingAdapter, чтобы сгладить некоторые оставшиеся проблемы:
@BindingAdapter("gameListData", "databaseState")
fun RecyclerView.bindListRecyclerView(gameList: PagedList<Game>?, databaseState: DatabaseState) {
val adapter = adapter as GameGridAdapter
/**
* We need to null out the old list or else the old games will briefly appear on screen
* after the ProgressBar disappears.
*/
adapter.submitList(null)
adapter.submitList(gameList) {
// This Runnable moves the list back to the top when changing sort options
if (databaseState == DatabaseState.Loading) {
scrollToPosition(0)
}
}
}