【问题标题】:How to make viewpager to not load pages again if they are already loaded如果页面已经加载,如何使 viewpager 不再加载页面
【发布时间】:2018-07-21 09:51:50
【问题描述】:

我有带有 7 个标签的 Viewpager,就像在 Play 商店中一样,如果我们点击主屏幕上的标签它会加载,如果我们再次点击该标签它不会加载,我希望如果我点击标签 1 它应该加载然后我让点击在标签 7 上,然后我再次点击标签 1,它不应该加载,只有在满足某些条件时才加载,我该怎么做?现在它只是带有适配器的简单视图寻呼机,例如:

  public class PagerNewProductAdapter extends FragmentStatePagerAdapter { 
      RealmList<SubCategory> categoryData;
      String categoryName;
      String categoryId;
      Env env;

      public PagerNewProductAdapter(Fragment fragment, RealmList<SubCategory> category, String categoryName, String categoryId, Env env) {
        super(fragment.getChildFragmentManager());
        categoryData = category;
        this.categoryId = categoryId;
        this.env = env;
        this.categoryName = categoryName;
      }

      @Override
      public int getCount() {
        return categoryData.size() + 2;
      }

      @Override
      public Fragment getItem(int position) {
        Fragment fragment;
        if (position == 0) {
          fragment= ProductFragment.newInstance("2", categoryId, categoryName);
        } else if (position == 1) {
          fragment= ProductFragment.newInstance("3", categoryId, categoryName);
        } else {
          fragment= ProductFragment.newInstance("1", categoryData.get(position - 2).getCategoryId(), categoryName);
        }
        return fragment;
      }

      @Override
      public CharSequence getPageTitle(int position) {
        if (position == 0) {
          // return env.appSubcategoryViewAll;
          return env.appSubcategoryViewAll;
        } else if (position == 1) {
          return env.appDashboardCBrands;
        } else {
          return categoryData.get(position - 2).getName();
        }
     }
  }

谢谢

【问题讨论】:

  • 您可以将 Fragment 缓存在一个数组中。
  • 怎么样,能解释一下

标签: java android android-fragments android-viewpager fragmentpageradapter


【解决方案1】:

只需像这样添加 setOffscreenPageLimit:

    viewPager = findViewById(R.id.viewpager);
    viewPager.setOffscreenPageLimit(3);

3 = viewpager 内的片段数。

【讨论】:

    【解决方案2】:

    我认为在这种情况下你可以使用SparseArray

    public class PagerNewProductAdapter extends FragmentStatePagerAdapter {
      private final SparseArray<Fragment> registeredFragments = new SparseArray<>();
      RealmList<SubCategory> categoryData;
      String categoryName;
      String categoryId;
      Env env;
    
      public PagerNewProductAdapter(Fragment fragment, RealmList<SubCategory> category, String categoryName, String categoryId, Env env) {
        super(fragment.getChildFragmentManager());
        categoryData = category;
        this.categoryId = categoryId;
        this.env = env;
        this.categoryName = categoryName;
      }
    
      @NonNull
      @Override
      public Object instantiateItem(ViewGroup container, int position) {
        if (registeredFragments.get(position) == null) {
          Object fragment = super.instantiateItem(container, position);
          registeredFragments.put(position, (BaseFragment) fragment);
          return fragment;
        } else {
          return registeredFragments.get(position);
        }
      }
    
      @Override
      public void destroyItem(ViewGroup container, int position, Object object) {
        super.destroyItem(container, position, object);
        registeredFragments.remove(position);
      }
    
      @Override
      public Fragment getItem(int position) {
        Fragment fragment;
        if (position == 0) {
            fragment= ProductFragment.newInstance("2", categoryId, categoryName);
        } else if (position == 1) {
            fragment= ProductFragment.newInstance("3", categoryId, categoryName);
        } else {
            fragment= ProductFragment.newInstance("1", categoryData.get(position - 2).getCategoryId(), categoryName);
        }
        return fragment;
      }
    
      @Override
      public int getCount() {
        return categoryData.size() + 2;
      }
    
    
    
      @Override
      public CharSequence getPageTitle(int position) {
        if (position == 0) {
           // return env.appSubcategoryViewAll;
            return env.appSubcategoryViewAll;
        } else if (position == 1) {
            return env.appDashboardCBrands;
        } else {
            return categoryData.get(position - 2).getName();
        }
      }
    }
    

    【讨论】:

    • getItem 会保持不变吗? intantiateItem 之后的实现没有变化?还有destroyItem的作用是什么
    • instantiateItem() 调用 getItem 方法,该方法创建一个新片段。在实例化方法中,我们返回之前创建的片段以避免创建另一个片段。这是重用。需要一个方法 detroitem 来释放片段。在源代码中,您可以看到 destroyItem() 保存片段状态并从事务中删除片段
    • 它不是缓存片段,如果我点击第一个标签然后转到最后一个标签,然后再次点击第一个标签,它会再次加载
    【解决方案3】:

    我认为您需要使用 Fragmentation。它正在按照您的要求工作。如果您有任何疑问,请告诉我。

    第 1 步: 实现分片https://github.com/YoKeyword/Fragmentation

    第 2 步: 从 SupportActivity 而不是 AppCompatActivity 扩展您的活动 从 SupportFragment 而不是 Fragment 扩展您的片段

    第 3 步: 从片段中删除 onresume 和 onpause 方法

    第 4 步: 调用 onPause();在 onViewCreated 方法中

    @Override
        public void onSupportVisible() {
            super.onSupportVisible();
           onResume();
            if(!isLoaded){
                isLoaded = true;
    //Load your data here 
    }
    }
    @Override
        public void onSupportInvisible() {
            super.onSupportInvisible();
           onPause();
        }
    

    第 5 步: 设置限制 viewPager.setOffscreenPageLimit(numberi);

    快乐编码。

    【讨论】:

      【解决方案4】:

      您可以将之前创建的 Fragment 存储在一个数组中。这确保我们将使用先前创建的实例(如果它存在于我们的 Array 中)。

      public class PagerNewProductAdapter extends FragmentStatePagerAdapter { 
            Fragment[] cache;
            RealmList<SubCategory> categoryData;
            ...
      
            public PagerNewProductAdapter(Fragment fragment, RealmList<SubCategory> category, String categoryName, String categoryId, Env env) {
              ...
              this.categoryName = categoryName;
              this.cache = new Fragment[getCount()];
            }
      
            @Override
            public int getCount() {
              return categoryData.size() + 2;
            }
      
            @Override
            public Fragment getItem(int position) {
      
              Fragment cachedFragment = cache[position]
              if(cachedFragment == null){
                  if (position == 0) {
                      cache[position] = ProductFragment.newInstance("2", categoryId, categoryName);
                      cachedFragment = cache[position];
                  } else if (position == 1) {
                      cache[position] = ProductFragment.newInstance("3", categoryId, categoryName);
                      cachedFragment = cache[position];
                  } else {
                      cache[position]= ProductFragment.newInstance("1", categoryData.get(position - 2).getCategoryId(), categoryName);
                      cachedFragment = cache[position];
                  }
              }
              return cachedFragment;
            }
            ...
        }
      

      【讨论】:

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