<i id='daoCT'><tr id='daoCT'><dt id='daoCT'><q id='daoCT'><span id='daoCT'><b id='daoCT'><form id='daoCT'><ins id='daoCT'></ins><ul id='daoCT'></ul><sub id='daoCT'></sub></form><legend id='daoCT'></legend><bdo id='daoCT'><pre id='daoCT'><center id='daoCT'></center></pre></bdo></b><th id='daoCT'></th></span></q></dt></tr></i><div id='daoCT'><tfoot id='daoCT'></tfoot><dl id='daoCT'><fieldset id='daoCT'></fieldset></dl></div>

  • <legend id='daoCT'><style id='daoCT'><dir id='daoCT'><q id='daoCT'></q></dir></style></legend>

    1. <tfoot id='daoCT'></tfoot>
        • <bdo id='daoCT'></bdo><ul id='daoCT'></ul>

      1. <small id='daoCT'></small><noframes id='daoCT'>

        带有视图模型和实时数据的 ViewPager,所有 6 个选项卡数据都替换为最后一个选项卡数据

        时间:2023-10-04
      2. <legend id='R3LGt'><style id='R3LGt'><dir id='R3LGt'><q id='R3LGt'></q></dir></style></legend>
          • <bdo id='R3LGt'></bdo><ul id='R3LGt'></ul>
              <tbody id='R3LGt'></tbody>
          • <i id='R3LGt'><tr id='R3LGt'><dt id='R3LGt'><q id='R3LGt'><span id='R3LGt'><b id='R3LGt'><form id='R3LGt'><ins id='R3LGt'></ins><ul id='R3LGt'></ul><sub id='R3LGt'></sub></form><legend id='R3LGt'></legend><bdo id='R3LGt'><pre id='R3LGt'><center id='R3LGt'></center></pre></bdo></b><th id='R3LGt'></th></span></q></dt></tr></i><div id='R3LGt'><tfoot id='R3LGt'></tfoot><dl id='R3LGt'><fieldset id='R3LGt'></fieldset></dl></div>

            <tfoot id='R3LGt'></tfoot>

                  <small id='R3LGt'></small><noframes id='R3LGt'>

                  本文介绍了带有视图模型和实时数据的 ViewPager,所有 6 个选项卡数据都替换为最后一个选项卡数据的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着跟版网的小编来一起学习吧!

                  问题描述

                  我正在开发一个带有 6 个 tabsViewPager,其中只有一个片段 TimesListFragment

                  I am working on a ViewPager with 6 tabs where it has only one fragment TimesListFragment

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

                  Depending on the arguments passed to TimesListFragment it calls api eg; science , technology, travel etc

                  我的应用程序遵循了 Google 的 GithubBrowserSample

                  I have followed Google's GithubBrowserSample for my app

                  我有 TimesListFragment -> TimesViewModel -> TimesRepository

                  I have TimesListFragment -> TimesViewModel -> TimesRepository

                  有 6 个选项卡,当我点击 api 时,所有选项卡都显示相同的结果,如果最后一个 argument

                  There are 6 tabs , when I hit the api all the tabs show the same result which if of the last 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参数的数据

                  issue : all tabs shows data of travel arguments

                  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
                      }
                  }
                  

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

                  注意:这两个方法都在 TimesListFragmnet

                  推荐答案

                  这应该是由于您的 ViewModel 而发生的.

                  This should be happening due to your ViewModel.

                  由于 ViewModel 的设计方式,每个 ActivityFragment 通常有一个 ViewModel工作.使用 ViewModel 的主要好处之一是它的生命周期与 Fragment 的生命周期完全分开,因此,您的 Fragment 可以多次销毁和重新创建,您仍然可以恢复存储在 ViewModel 中的当前数据.

                  Typically, there's one ViewModel per Activity or Fragment, due to the way a ViewModel is designed to work. One of the major benefits in using a ViewModel is that it's lifecycle is completely separate from the lifecycle of your Fragment, therefore, your Fragment can be destroyed and recreated multiple times and you'll still be able to restore current data that's stored in your ViewModel.

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

                  Therefore, this means that with the typical code to fetch the ViewModel from the ViewModelProviders, you'll be fetching the exact same ViewModel.

                  通常,这不会导致问题,但在您的 ViewPager 中,您正在重用 最有可能的相同 TimesListFragment调用相同的 ViewModel,从而导致每个片段显示相同的数据.

                  Typically, this won't cause a problem, but in your ViewPager, you're reusing the same TimesListFragment which is most likely calling up the same ViewModel, therefore causing each fragment to show the same data.

                  解决方案是使用:

                  ViewModelProviders.of(this).get(KEY, TimesViewModel::class.java)
                  

                  注意用于区分需要获取的 ViewModel 的 KEY.因此,通过使用 ViewPager 中的位置作为唯一键,您应该能够为每个 TimesListFragment 拥有一个唯一的 ViewModel.

                  Note the KEY which is used to differentiate between the ViewModels that needs to be fetched. So by using the positions in the ViewPager as a unique key, you should be able to have a unique ViewModel for each TimesListFragment.

                  这篇关于带有视图模型和实时数据的 ViewPager,所有 6 个选项卡数据都替换为最后一个选项卡数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!

                  上一篇:如何将 Android ViewPager2 的高度包装到当前项目的高度? 下一篇:更改 viewPager 滑动方向

                  相关文章

                    <bdo id='zRa7R'></bdo><ul id='zRa7R'></ul>
                1. <tfoot id='zRa7R'></tfoot>

                2. <small id='zRa7R'></small><noframes id='zRa7R'>

                  <legend id='zRa7R'><style id='zRa7R'><dir id='zRa7R'><q id='zRa7R'></q></dir></style></legend>

                    <i id='zRa7R'><tr id='zRa7R'><dt id='zRa7R'><q id='zRa7R'><span id='zRa7R'><b id='zRa7R'><form id='zRa7R'><ins id='zRa7R'></ins><ul id='zRa7R'></ul><sub id='zRa7R'></sub></form><legend id='zRa7R'></legend><bdo id='zRa7R'><pre id='zRa7R'><center id='zRa7R'></center></pre></bdo></b><th id='zRa7R'></th></span></q></dt></tr></i><div id='zRa7R'><tfoot id='zRa7R'></tfoot><dl id='zRa7R'><fieldset id='zRa7R'></fieldset></dl></div>