ViewPager.setOffscreenPageLimit(0)无法按预期工作

Chr*_*acy 97 android android-viewpager android-support-library

我在我的ViewPager实例中使用的片段是非常耗费资源的,所以我只想一次加载一个.当我尝试以下内容时:

mViewPager.setOffscreenPageLimit(0);
mViewPager.setAdapter(mPagerAdapter);
Run Code Online (Sandbox Code Playgroud)

我的FragmentStatePagerAdapter.getItem(int position)覆盖功能被调用3次,这是我打电话时发生的事情mViewPager.setOffscreenPageLimit(1).我希望它只被调用一次,因为我指定了0个屏幕外页面.

我相信我正在正确地呼唤一切,因为如果我打电话mViewPager.setOffscreenPageLimit(2),FragmentStatePagerAdapter.getItem(int position)就像我期望的那样被召唤5次.

ViewPager是否需要至少1个屏幕外页面,或者我在这里做错了什么?

Tyl*_*vis 121

我找到的最佳方法是setUserVisibleHint
将其添加到您的片段中

@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
    super.setUserVisibleHint(isVisibleToUser);
    if (isVisibleToUser) {
        // load data here
    }else{
       // fragment is no longer visible
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 最佳解决方案现已弃用 (4认同)

Com*_*are 111

ViewPager是否需要至少1个屏幕外页面

是.如果我正确地阅读源代码,您应该在LogCat中收到有关此内容的警告,例如:

Requested offscreen page limit 0 too small; defaulting to 1
Run Code Online (Sandbox Code Playgroud)

  • @Haraldo:"当然这有可能吗?" - 不是`ViewPager`.`ViewPager`创建这些片段以便存在视图,因此用户可以在它们之间滑动,动画效果显示旧视图滑出屏幕并且新视图滑动到屏幕上.欢迎您尝试编写自己的`ViewPager`,它可以在不存在的东西之间滑动.您可以访问https://code.google.com/p/android/issues/detail?id=56667#c3了解更多相关信息. (11认同)
  • 这不是解决方案!我想只加载1个片段而不是2.当然这有可能吗? (5认同)
  • @Haraldo:"一个默认的空片段可以是一个占位符,例如,直到一个片段已加载" - 欢迎你今天在你的片段中有一个占位符,使用`ViewPager`的现有实现,你可以用真实替换它内容可用. (5认同)
  • 是的,我已经读过这个问题.只是不合逻辑.我希望能将`setOffscreenPageLimit(0)`改为0.然后我可以自己处理后果.默认的空片段可以是占位符,例如在片段已加载之前.所有这些都可以在UI线程之外进行.无论如何,我没有想太多. (2认同)
  • onPageChangeListener似乎是解决方案。 (2认同)

小智 7

你可以尝试这样:

public abstract class LazyFragment extends Fragment {
    protected boolean isVisible;
    /**
     * ?????Fragment??????.
     * @param isVisibleToUser
     */
    @Override
    public void setUserVisibleHint(boolean isVisibleToUser) {
        super.setUserVisibleHint(isVisibleToUser);
        if(getUserVisibleHint()) {
            isVisible = true;
            onVisible();
        } else {
            isVisible = false;
            onInvisible();
        }
    }
    protected void onVisible(){
        lazyLoad();
    }
    protected abstract void lazyLoad();
    protected void onInvisible(){}
Run Code Online (Sandbox Code Playgroud)

protected abstract void lazyLoad();
protected void onInvisible(){}
Run Code Online (Sandbox Code Playgroud)


小智 7

先添加

   boolean isFragmentLoaded = false;
Run Code Online (Sandbox Code Playgroud)

@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
    super.setUserVisibleHint(isVisibleToUser);
    if (isVisibleToUser && !isFragmentLoaded) {
        //Load Your Data Here like.... new GetContacts().execute();

        isFragmentLoaded = true;
    }
else{
     }
}
Run Code Online (Sandbox Code Playgroud)

  • 但是这个方法在onCreateView之前调用 (6认同)