【问题标题】:Android - ViewPager Adapter, set primary item before adapter is instantiatedAndroid - ViewPager Adapter,在实例化适配器之前设置主要项目
【发布时间】:2014-09-25 22:32:21
【问题描述】:

我知道我能做到

 viewPager.setCurrentItem(position) 

将我的视图寻呼机设置在所需位置。我的问题是在实例化适配器之前是否以及如何执行此操作。

意思是如果我这样做了

pagerAdapter = new ViewPagerAdapter(arg1,arg2....);
viewPager.setAdapter(pagerAdapter);
viewPager.setCurrentItem(position);

item 0 是第一次构建,然后在所需位置的项目也被构建。这需要双倍的时间......在我的适配器中,每个项目都需要大量的工作来构建,所以如果可能的话,最好避免构建 0 位置的项目。也许通过在适配器实例化时将所需位置作为参数传递...?

有什么办法吗?

【问题讨论】:

    标签: android android-viewpager setcurrentvalue


    【解决方案1】:

    如果您担心时间和工作,我会尽量避免在位置 0 构建页面,直到构建所需的页面。您可以在适配器中使用变量让我们说“desiredPageHasBeenBuilt”,当请求位置 0 的项目时,如果变量 desiredPageHasBeenBuilt 为 false,则可以返回“空页面”,当您想要的页面已构建时,将变量设置为 true 并且可以构建第 0 页。

    【讨论】:

    • 请举例;)
    【解决方案2】:

    对于适用于 Android M 和旧版本的解决方案,请按如下方式使用反射:

    int currentItem = 5;
    
    // Set initial position first...
    Field field = ViewPager.class.getDeclaredField("mRestoredCurItem");
    field.setAccessible(true);
    field.set(mPager, currentItem);
    
    // ...and then set adapter
    mPager.setAdapter(adapter);
    

    使用反射是安全的,因为您可以控制ViewPager 的实现(它包含在您的应用中)。

    如果您使用 Proguard,则需要在其配置中包含以下内容:

    -keepclassmembers class android.support.v4.view.ViewPager {
        private int mRestoredCurItem;
    }  
    

    否则mRestoredCurItem 字段将被 Proguard 重命名。

    【讨论】:

      【解决方案3】:

      您可以只设置空白适配器,然后以这种方式设置您的真实适配器,您将“欺骗”viewpager,并且您想要加载任何您不想加载的数据。

      this.viewPager.setAdapter(new PagerAdapter() {
              @Override
              public int getCount() {
                  return 0;
              }
      
              @Override
              public boolean isViewFromObject(View view, Object object) {
                  return false;
              }
          });
      this.viewPager.setCurrentItem(imagePosition, false);
      this.viewPager.setAdapter(adapter);
      this.viewPager.setCurrentItem(imagePosition, false);
      

      【讨论】:

      • 这不起作用,只要您调用 setAdapter,ViewPager 就会在内部将当前项目重置为 0
      【解决方案4】:

      您可以通过调用 onRestoreInstanceState 来欺骗 viewpager,使其在设置适配器之前从给定位置开始,如下所示:

      int currentItem = 5;
      
      Parcel parcel = Parcel.obtain();
      writeParcelable(BaseSavedState.EMPTY_STATE, 0);
      
      writeInt(currentItem);
      writeParcelable(null, 0);
      
      setDataPosition(0);
      SavedState savedState = ViewPager.SavedState.CREATOR.createFromParcel(parcel);
      
      mPager.onRestoreInstanceState(savedState);
      
      mPager.setAdapter(mAdapter);
      

      【讨论】:

      • 不幸的是,这在 Android M 中不再起作用,请参阅我的新答案
      【解决方案5】:

      也许这不是您要寻找的答案,但您是否按照设计的方式尝试过?在页面片段附加到屏幕之前,不要在页面片段上开始繁重的工作。这样,您将获得您想要的行为,而无需破解 android 实现。

      【讨论】:

        【解决方案6】:

        你可以做到这一点:

        将所有繁重的工作重构为一个函数,因为创建fragment 并不需要太多时间,并且仅在用户通过在OnPageChangeListener 侦听器中调用该函数并在

        @Override
        public void onPageSelected(int position){
            // call your function that do heavy working  
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-12-14
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多