kar*_*nji 6 android android-viewpager android-livedata android-viewmodel
我对工作ViewPager有6个tabs地方只有一个片段TimesListFragment
根据传递给TimesListFragment它的参数调用api eg; 科学,技术,旅行等
我已经GithubBrowserSample为我的应用关注了Google的
我有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]
}
}
Run Code Online (Sandbox Code Playgroud)
问题:所有选项卡都显示travel参数数据
TimesViewModel
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
}
}
Run Code Online (Sandbox Code Playgroud)
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()
}
Run Code Online (Sandbox Code Playgroud)
ApiService.kt
interface ApiService {
@GET("svc/topstories/v2/{section}.json?")
fun getTopStories(@Path ("section") section:String,@Query("api-key") apiKey:String)
:LiveData<ApiResponse<TimesStoriesResponse>>
}
Run Code Online (Sandbox Code Playgroud)
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)
}
}
})
}
Run Code Online (Sandbox Code Playgroud)
注意:两种方法都在的onViewCreated()中调用 TimesListFragmnet
Jac*_*key 14
这应该是由于您的情况而发生的ViewModel。
通常,由于a 的设计工作方式,ViewModel每个Activity或都有一个。使用a的主要好处之一是它的生命周期与您的生命周期完全分开,因此,您可以多次销毁和重新创建您的生命,并且仍然可以恢复存储在其中的当前数据。FragmentViewModelViewModelFragmentFragmentViewModel
因此,这意味着,典型的代码来获取ViewModel从ViewModelProviders,你会获取完全相同的ViewModel。
通常,这不会造成问题,但是在您的中ViewPager,您正在重用相同的内容TimesListFragment,而最有可能调用的是相同的内容ViewModel,因此导致每个片段显示相同的数据。
解决方案是使用:
ViewModelProviders.of(this).get(KEY, TimesViewModel::class.java)
Run Code Online (Sandbox Code Playgroud)
请注意KEY,该键用于区分需要获取的ViewModel。因此,通过使用中的位置ViewPager作为唯一键,您应该能够ViewModel为每个设置唯一TimesListFragment。
| 归档时间: |
|
| 查看次数: |
1971 次 |
| 最近记录: |