0

固定的

见下文

如果一张图片值 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))  
    }  
}
4

1 回答 1

1

事实证明,修复非常简单。我只需要使用 Activity 作为传递给 ViewModel 的生命周期。

显示片段


    // ...
    override fun onAttach(context: Context) {  
        super.onAttach(context)  

        AndroidSupportInjection.inject(this)
        // CHANGED ONE LINE AND IT WORKS
        // (changed this to activity!!)  
        // CHANGED ONE LINE AND IT WORKS
        showsViewModel = ViewModelProviders.of(activity!!, factory).get(ShowsViewModel::class.java)  
    } 
    // ...

}
于 2019-10-03T07:23:37.827 回答