固定的
如果一张图片值 1000 个字,那么一个视频就值很多字。这是该问题的视频解释。
我已经包含了一个视频,因为它使事情变得更加清晰。问题:当我第一次加载包含需要切换状态的项目列表的片段时,我可以很好地切换该状态。我将更新发送到 Room 数据库,然后将更改发送回我的 ViewModel,然后 ViewModel 将它们分派到 Fragment。
但是,当我离开片段并返回时,不再分派更改。我不知道我是否在做一些非常愚蠢的事情,或者这是一个错误。
如果相关的话,我也在使用 Jetpack Navigation 组件。我将在下面包含代码。
如果您需要查看下面引用的任何其他代码,请告诉我,我会将其添加到问题中。
非常感谢您的时间和考虑。
显示片段
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)
)
}
}
秀道
@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)
}
显示视图模型
@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))
}
}