База данных Android-комнат обновляется, но не отправляет обновления по возвращении во фрагмент - PullRequest
0 голосов
/ 03 октября 2019

ИСПРАВЛЕНО

СМОТРЕТЬ НИЖЕ

Если картинка стоит 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))  
    }  
}

1 Ответ

0 голосов
/ 03 октября 2019

Оказывается, исправить это очень просто. Мне просто нужно было использовать Activity в качестве жизненного цикла, который был передан в ViewModel.

ShowsFragment


    // ...
    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)  
    } 
    // ...

}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...