ИСПРАВЛЕНО
СМОТРЕТЬ НИЖЕ
Если картинка стоит 1000 слов, видео стоит, как много слов. Вот видео объяснение проблемы.
Я включил видео, так как оно делает вещи намного понятнее. Проблема: Когда я впервые загружаю фрагмент, содержащий список элементов с состоянием, которое мне нужно переключить, я могу переключить это состояние очень хорошо. Я отправляю обновление в базу данных Room, и изменения отправляются обратно в мою ViewModel, которая затем отправляет их фрагменту.
Однако, когда я покидаю фрагмент и возвращаюсь, изменения больше не отправляются. Я не знаю, делаю ли я что-то невероятно глупое или это ошибка.
Я также использую навигационные компоненты Jetpack, если это актуально. Я добавлю код ниже.
Пожалуйста, дайте мне знать, если вам нужен какой-либо другой код, указанный ниже, и я добавлю его к вопросу.
Большое спасибо за ваше времяи рассмотрение.
ShowsFragment
class ShowsFragment : Fragment(), ShowClickListener, Observer<Resource<List<ShowDomainModel>>> {
@Inject
lateinit var factory: ViewModelFactory
@Inject
lateinit var adapter: ShowsAdapter
private lateinit var showsViewModel: ShowsViewModel
override fun onAttach(context: Context) {
super.onAttach(context)
AndroidSupportInjection.inject(this)
showsViewModel = ViewModelProviders.of(this, factory).get(ShowsViewModel::class.java)
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?
) = inflater.inflate(R.layout.fragment_shows, container, false)!!
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
adapter.clickListener = this
shows.adapter = adapter
val shows = showsViewModel.getShows()
shows.observe(this, this)
}
override fun onChanged(resource: Resource<List<ShowDomainModel>>) {
Timber.d("onChanged")
when (resource.state) {
State.SUCCESS -> {
adapter.shows = resource.data!!
adapter.notifyDataSetChanged()
}
State.LOADING -> Unit
State.ERROR -> TODO("Handle error state in ShowsFragment")
}
}
override fun onShowFavoriteClicked(show: ShowDomainModel) {
if (show.favorite) {
showsViewModel.unfavoriteShow(show.playlistId)
} else {
showsViewModel.favoriteShow(show.playlistId)
}
}
override fun onShowClicked(show: ShowDomainModel) {
findNavController().navigate(
ShowsFragmentDirections.showEpisodes(show.name, show.playlistId)
)
}
}
ShowsDao
@Dao
abstract class ShowsDao {
@Query("SELECT * FROM $TABLE_NAME")
abstract fun getShows(): Observable<List<ShowCacheModel>>
@Insert(onConflict = OnConflictStrategy.IGNORE)
abstract fun insertShows(shows: List<ShowCacheModel>)
@Query("SELECT * from $TABLE_NAME WHERE favorite = 1")
abstract fun getFavoriteShows(): Observable<List<ShowCacheModel>>
@Query("UPDATE $TABLE_NAME SET favorite = :favorite WHERE $COLUMN_SHOW_ID = :showId")
abstract fun setFavorite(showId: String, favorite: Boolean)
}
ShowsViewModel
@Singleton
class ShowsViewModel @Inject constructor(
private val getShows: GetShows,
private val addShowToFavorites: AddShowToFavorites,
private val removeShowFromFavorites: RemoveShowFromFavorites
) : ViewModel() {
private val shows: MutableLiveData<Resource<List<ShowDomainModel>>> = MutableLiveData()
init {
shows.postValue(Resource.loading())
getShows.execute(GetShowsObserver())
}
override fun onCleared() {
getShows.dispose()
super.onCleared()
}
fun getShows(): LiveData<Resource<List<ShowDomainModel>>> = shows
fun favoriteShow(id: String) = addShowToFavorites.execute(
AddShowToFavoritesObserver(),
AddShowToFavorites.Params.forShow(id)
)
fun unfavoriteShow(id: String) = removeShowFromFavorites.execute(
RemoveShowFromFavoritesObserver(),
RemoveShowFromFavorites.Params.forShow(id)
)
inner class GetShowsObserver : DisposableObserver<List<ShowDomainModel>>() {
override fun onComplete() {
Log.d("ShowsViewModel","onComplete")
throw RuntimeException("GetShows should not complete, should be observing changes to data.")
}
override fun onNext(showList: List<ShowDomainModel>) {
shows.postValue(Resource.success(showList))
}
override fun onError(e: Throwable) {
shows.postValue(Resource.error(e.localizedMessage))
}
}
inner class AddShowToFavoritesObserver : DisposableCompletableObserver() {
override fun onComplete() = Unit
override fun onError(e: Throwable) =
shows.postValue(Resource.error(e.localizedMessage))
}
inner class RemoveShowFromFavoritesObserver : DisposableCompletableObserver() {
override fun onComplete() = Unit
override fun onError(e: Throwable) =
shows.postValue(Resource.error(e.localizedMessage))
}
}