具有viewmodel和实时数据的ViewPager,所有6个选项卡数据都被最后一个选项卡数据替换

问题描述 投票:2回答:1

我正在研究ViewPager与6 tabs,其中只有一个片段TimesListFragment

根据传递给TimesListFragment的参数,它调用api eg;科学,技术,旅游等

我已经关注谷歌的GithubBrowserSample我的应用程序

我有qazxsw poi - > qazxsw poi - > qazxsw poi

有6个标签,当我点击api所有标签显示相同的结果,如果最后一个TimesListFragment

StoriesPagerAdapter.kt

TimesViewModel

问题:所有选项卡都显示TimesRepository参数的数据

时间视图模型

argument

TimesRepository.kt

class StoriesPagerAdapter(fragmentManager: FragmentManager?)
    :FragmentStatePagerAdapter(fragmentManager){
    private val sections= arrayListOf("science","technology","business","world","movies","travel")
    override fun getItem(position: Int): Fragment {
        return TimesListFragment.newInstance(sections[position])
    }
    override fun getCount(): Int {
        return sections.size
    }
    override fun getPageTitle(position: Int): CharSequence? {
        return sections[position]
    }
}

ApiService.kt

travel

TimesListFragment.kt

class TimesViewModel @Inject constructor(private val timesRepository: TimesRepository) :
        ViewModel() {
    lateinit var data: LiveData<Resource<TimesStoriesResponse>>
    fun fetchStories(section:String): LiveData<Resource<TimesStoriesResponse>> {
        data = timesRepository.loadStories(section)
        return data
    }
}

注意:这两个方法都在class TimesRepository @Inject constructor(private val apiService: ApiService, private val timesDao: TimesDao, private val appExecutors: AppExecutors) { private val repoListRateLimit = RateLimiter<String>(10, TimeUnit.MINUTES) fun loadStories(section:String): LiveData<Resource<TimesStoriesResponse>> { return object : NetworkBoundResource<TimesStoriesResponse, TimesStoriesResponse>(appExecutors) { override fun saveCallResult(item: TimesStoriesResponse) { timesDao.insert(item) } override fun shouldFetch(data: TimesStoriesResponse?): Boolean { return data == null || repoListRateLimit.shouldFetch(section) } override fun loadFromDb() = timesDao.load() override fun createCall() = apiService.getTopStories(section,ConfigConstant.TIMES_KEY) override fun onFetchFailed() { repoListRateLimit.reset(section) } }.asLiveData() } 的onViewCreated()中调用

android android-viewpager android-livedata android-viewmodel
1个回答
8
投票

这应该是由于你的interface ApiService { @GET("svc/topstories/v2/{section}.json?") fun getTopStories(@Path ("section") section:String,@Query("api-key") apiKey:String) :LiveData<ApiResponse<TimesStoriesResponse>> } 发生。

通常,每个private fun initViewModel() { viewModel = ViewModelProviders.of(this, viewModelFactory).get(section,TimesViewModel::class.java) } private fun initData() { viewModel?.fetchStories(section)?.observe(this, Observer { when (it?.status) { Status.LOADING -> { showLoading(true) showError(false,null) } Status.SUCCESS -> { showLoading(false) showError(false,null) showSuccessData(it.data) } Status.ERROR -> { showLoading(false) showError(true,it.message) } } }) } TimesListFragmnet有一个ViewModel,因为ViewModel的设计方式。使用Activity的一个主要好处是它的生命周期与你的Fragment的生命周期完全分开,因此,你的ViewModel可以被多次销毁和重建,你仍然可以恢复存储在你的ViewModel中的当前数据。

因此,这意味着使用从Fragment获取Fragment的典型代码,您将获取完全相同的ViewModel

通常情况下,这不会引起问题,但是在你的ViewModel中,你重复使用相同的ViewModelProviders,它最有可能调用相同的ViewModel,因此导致每个片段显示相同的数据。

解决方案是使用:

ViewPager

注意KEY,用于区分需要获取的ViewModel。因此,通过使用TimesListFragment中的位置作为唯一键,您应该能够为每个ViewModel提供唯一的ViewModelProviders.of(this).get(KEY, TimesViewModel::class.java)

© www.soinside.com 2019 - 2024. All rights reserved.