android - 带有视图模型和实时数据的 ViewPager,所有 6 个选项卡数据都替换为最后一个选项卡数据
问题描述
我正在研究一个只有一个片段的ViewPager
6tabs
TimesListFragment
根据传递给TimesListFragment
它的参数调用 api 例如;科学、技术、旅游等
我GithubBrowserSample
为我的应用遵循了谷歌的
我有TimesListFragment
-> TimesViewModel
->TimesRepository
有 6 个选项卡,当我点击 api 时,所有选项卡都显示相同的结果,如果是最后一个argument
StoriesPagerAdapter.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]
}
}
问题:所有选项卡都显示travel
参数数据
时代视图模型
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
}
}
TimesRepository.kt
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()
}
ApiService.kt
interface ApiService {
@GET("svc/topstories/v2/{section}.json?")
fun getTopStories(@Path ("section") section:String,@Query("api-key") apiKey:String)
:LiveData<ApiResponse<TimesStoriesResponse>>
}
TimesListFragment.kt
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)
}
}
})
}
注意:这两种方法都在 onViewCreated() 中调用TimesListFragmnet
解决方案
这应该是由于您的ViewModel
.
通常,由于 a的设计工作方式,ViewModel
每个Activity
or都有一个。使用 a 的主要好处之一是它的生命周期与您的.Fragment
ViewModel
ViewModel
Fragment
Fragment
ViewModel
因此,这意味着使用ViewModel
从中获取 的典型代码ViewModelProviders
,您将获取完全相同的ViewModel
.
通常,这不会导致问题,但是在您的 中ViewPager
,您正在重用相同TimesListFragment
的,最有可能调用相同的ViewModel
,因此导致每个片段显示相同的数据。
解决方案是使用:
ViewModelProviders.of(this).get(KEY, TimesViewModel::class.java)
请注意用于区分需要获取的 ViewModel 的 KEY。因此,通过将 中的位置ViewPager
用作唯一键,您应该能够ViewModel
为每个TimesListFragment
.
推荐阅读
- api - Evernote API 已获批准,但无法为生产服务器创建开发者令牌
- c++ - 我们可以在 if-else 语句中声明一个对象吗?
- python - 将来自 for 循环的数组结果存储在字典中
- sql - SQL Server Datediff() 函数不起作用
- gremlin - Gremlin Scala - 批量加载顶点
- html - 使用 xpath 从具有特定类的表中获取最后一个 td
- xamarin - Visual Studio macOS 无法为 Xamarin.Forms 应用生成 HTML 文档
- keras - keras 中的 VGG 瓶颈特征 + LSTM
- asp.net-core - 如何将非表单数据从 Razor 页面发布到页面模型
- angular - 如果没有 waitForAngularEnabled(false),量角器测试将无法在 Angular 4 站点上运行