setoffscreenpagelimit(0)不像预期的那样工作。

时间:2021-09-22 21:45:21

The fragments I use in my ViewPager instance are quite resource intensive, so I'd only like to load one at a time. When I try the following:

我在ViewPager实例中使用的片段非常占用资源,所以我只希望一次加载一个片段。当我尝试以下方法:

mViewPager.setOffscreenPageLimit(0);
mViewPager.setAdapter(mPagerAdapter);

My FragmentStatePagerAdapter.getItem(int position) override function is called 3 times, which is what happens when I call mViewPager.setOffscreenPageLimit(1). I would expect it to only be called once, because I specified 0 offscreen pages.

我的FragmentStatePagerAdapter。getItem(int position)重写函数被调用3次,这就是我调用mviewpager . setoffscreenlimit(1)时发生的情况。我希望它只被调用一次,因为我指定了0个屏幕外的页面。

I believe I'm calling everything correctly, because if I call mViewPager.setOffscreenPageLimit(2), FragmentStatePagerAdapter.getItem(int position) is called 5 times as I would expect.

我相信我调用的一切都是正确的,因为如果我调用mViewPager.setOffscreenPageLimit(2), FragmentStatePagerAdapter。getItem(int位置)被调用5次。

Does ViewPager require a minimum of 1 offscreen pages, or am I doing something wrong here?

ViewPager需要至少一个屏幕外的页面吗?还是我在这里做错了什么?

8 个解决方案

#1


99  

Does ViewPager require a minimum of 1 offscreen pages

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

Yes. If I am reading the source code correctly, you should be getting a warning about this in LogCat, something like:

是的。如果我正确地阅读了源代码,您应该在LogCat中得到关于这一点的警告,比如:

Requested offscreen page limit 0 too small; defaulting to 1

#2


103  

The best way that I found was setUserVisibleHint
add this to your fragment

我找到的最好的方法是setUserVisibleHint:将这个添加到您的片段中

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

#3


7  

First Add

第一次添加

   boolean isFragmentLoaded = false;

than

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

        isFragmentLoaded = true;
    }
else{
     }
}

#4


5  

You can try like this :

你可以这样尝试:

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

protected abstract void lazyLoad();
protected void onInvisible(){}

#5


1  

ViewPager is default to load the next page(Fragment) which you can't change by setOffscreenPageLimit(0). But you can do something to hack. You can implement onPageSelected function in Activity containing the ViewPager. In the next Fragment(which you don't want to load), you write a function let's say showViewContent() where you put in all resource consuming init code and do nothing before onResume() method. Then call showViewContent() function inside onPageSelected. Hope this will help.

ViewPager默认加载下一个页面(片段),您无法通过setOffscreenPageLimit(0)更改该页面。但你可以做点什么。您可以在包含ViewPager的活动中实现onpagesselected函数。在下一个片段(您不想加载)中,您将编写一个函数,比如showViewContent(),在这个函数中,您将所有资源使用init代码,在onResume()方法之前不做任何事情。然后调用showViewContent()函数在onpages民选中。希望这将帮助。

#6


0  

for the "instantiateItem" function, just prepare the fragment, but don't load the heavy content.

对于“实例化项”函数,只需要准备片段,但不要加载繁重的内容。

Use "onPageChangeListener" , so that each time you go to a specific page, you load its heavy content and show it.

使用“onPageChangeListener”,这样每次您访问特定的页面时,就会加载它的大量内容并显示它。

#7


0  

this may be old thread but this seems to work for me. Override this function :

这可能是旧线,但这似乎对我有用。重写这个函数:

@Override
public void setMenuVisibility(boolean menuVisible) { 
    super.setMenuVisibility(menuVisible);

    if ( menuVisible ) {
        /**
         * Load your stuffs here.
         */
    } else  { 
        /**
         * Fragment not currently Visible.
         */
    } 
}

happy codings...

快乐的编码…

#8


0  

I kind of have the same problem. I found some useful code on this site and transform it.

我也有同样的问题。我在这个网站上找到了一些有用的代码并进行了转换。

The min int for mViewPager.setOffscreenPageLimit(...); is 1, so even if you change it to 0 you will still have 2 pages loaded.

用于mViewPager.setOffscreenPageLimit(…)的最小int数;是1,所以即使你把它改成0你仍然会有2页被载入。

First thing to do is to create a static int we will call maxPageCount and override FragmentStatePagerAdapter method getCount() to return maxPageCount:

首先要做的是创建一个静态int,我们将调用maxPageCount并覆盖FragmentStatePagerAdapter方法getCount()返回maxPageCount:

    @Override
    public int getCount() {
        return maxPageCount;
    }

Create then a static method accessible from any where in the program that will allow you to change this maxCount:

然后创建一个可以从程序中任何位置访问的静态方法,允许您更改这个maxCount:

public static void addPage(){
    maxPageCount++; //or maxPageCount = fragmentPosition+2
    mFragmentStatePagerAdapter.notifyDataSetChanged(); //notifyDataSetChanged is important here.
}

Now initialize maxPageCount to 1. When ever you want you can add another page. In my case when I needed the user to treat the current page first before generated the other. He do it and then, without problem can swipe to the next page.

现在将maxPageCount初始化为1。当你需要的时候,你可以再添加一个页面。在我的例子中,当我需要用户在生成另一个页面之前先处理当前页面时。他做了,然后,没有问题可以滑动到下一页。

Hope it help someone.

希望它帮助别人。

#1


99  

Does ViewPager require a minimum of 1 offscreen pages

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

Yes. If I am reading the source code correctly, you should be getting a warning about this in LogCat, something like:

是的。如果我正确地阅读了源代码,您应该在LogCat中得到关于这一点的警告,比如:

Requested offscreen page limit 0 too small; defaulting to 1

#2


103  

The best way that I found was setUserVisibleHint
add this to your fragment

我找到的最好的方法是setUserVisibleHint:将这个添加到您的片段中

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

#3


7  

First Add

第一次添加

   boolean isFragmentLoaded = false;

than

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

        isFragmentLoaded = true;
    }
else{
     }
}

#4


5  

You can try like this :

你可以这样尝试:

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

protected abstract void lazyLoad();
protected void onInvisible(){}

#5


1  

ViewPager is default to load the next page(Fragment) which you can't change by setOffscreenPageLimit(0). But you can do something to hack. You can implement onPageSelected function in Activity containing the ViewPager. In the next Fragment(which you don't want to load), you write a function let's say showViewContent() where you put in all resource consuming init code and do nothing before onResume() method. Then call showViewContent() function inside onPageSelected. Hope this will help.

ViewPager默认加载下一个页面(片段),您无法通过setOffscreenPageLimit(0)更改该页面。但你可以做点什么。您可以在包含ViewPager的活动中实现onpagesselected函数。在下一个片段(您不想加载)中,您将编写一个函数,比如showViewContent(),在这个函数中,您将所有资源使用init代码,在onResume()方法之前不做任何事情。然后调用showViewContent()函数在onpages民选中。希望这将帮助。

#6


0  

for the "instantiateItem" function, just prepare the fragment, but don't load the heavy content.

对于“实例化项”函数,只需要准备片段,但不要加载繁重的内容。

Use "onPageChangeListener" , so that each time you go to a specific page, you load its heavy content and show it.

使用“onPageChangeListener”,这样每次您访问特定的页面时,就会加载它的大量内容并显示它。

#7


0  

this may be old thread but this seems to work for me. Override this function :

这可能是旧线,但这似乎对我有用。重写这个函数:

@Override
public void setMenuVisibility(boolean menuVisible) { 
    super.setMenuVisibility(menuVisible);

    if ( menuVisible ) {
        /**
         * Load your stuffs here.
         */
    } else  { 
        /**
         * Fragment not currently Visible.
         */
    } 
}

happy codings...

快乐的编码…

#8


0  

I kind of have the same problem. I found some useful code on this site and transform it.

我也有同样的问题。我在这个网站上找到了一些有用的代码并进行了转换。

The min int for mViewPager.setOffscreenPageLimit(...); is 1, so even if you change it to 0 you will still have 2 pages loaded.

用于mViewPager.setOffscreenPageLimit(…)的最小int数;是1,所以即使你把它改成0你仍然会有2页被载入。

First thing to do is to create a static int we will call maxPageCount and override FragmentStatePagerAdapter method getCount() to return maxPageCount:

首先要做的是创建一个静态int,我们将调用maxPageCount并覆盖FragmentStatePagerAdapter方法getCount()返回maxPageCount:

    @Override
    public int getCount() {
        return maxPageCount;
    }

Create then a static method accessible from any where in the program that will allow you to change this maxCount:

然后创建一个可以从程序中任何位置访问的静态方法,允许您更改这个maxCount:

public static void addPage(){
    maxPageCount++; //or maxPageCount = fragmentPosition+2
    mFragmentStatePagerAdapter.notifyDataSetChanged(); //notifyDataSetChanged is important here.
}

Now initialize maxPageCount to 1. When ever you want you can add another page. In my case when I needed the user to treat the current page first before generated the other. He do it and then, without problem can swipe to the next page.

现在将maxPageCount初始化为1。当你需要的时候,你可以再添加一个页面。在我的例子中,当我需要用户在生成另一个页面之前先处理当前页面时。他做了,然后,没有问题可以滑动到下一页。

Hope it help someone.

希望它帮助别人。