如何让我的ViewPager一次只加载一个页面,即setOffscreenPageLimit(0);

时间:2022-09-11 18:51:35

I understand the lowest number I can give setOffscreenPageLimit(int) is 1. but I need to load one page at a time because memory problems.

我理解我可以给setOffscreenPageLimit(int)的最小数字是1.但我需要一次加载一个页面因为内存问题。

Am i going to have to use the old style tabhost etc? or is there a way/hack I can make my viewPager load one page at a time?

我将不得不使用旧式tabhost等?或者有没有办法/黑客我可以让我的viewPager一次加载一页?

My Adapter extends BaseAdapter with the ViewHolder patern.

我的适配器使用ViewHolder patern扩展BaseAdapter。

5 个解决方案

#1


19  

I was having the same problem and I found the solution for it:

我遇到了同样的问题,我找到了解决方案:

Steps:

1) First Download the CustomViewPager Class from this link.

1)首先从此链接下载CustomViewPager类。

2) Use that class as mentioned below:

2)使用如下所述的类:

In Java:

CustomViewPager mViewPager;
mViewPager = (CustomViewPager) findViewById(R.id.swipePager);
mViewPager.setOffscreenPageLimit(0);

In XML:

<com.yourpackagename.CustomViewPager 
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/swipePager"
    android:layout_width="match_parent"
    android:layout_height="match_parent"/>

Now only one page will be loaded at once.

现在只能一次加载一个页面。

#2


14  

As far as I know, that is not possible when using the ViewPager. At least not, when you want your pages to be swipe-able.

据我所知,使用ViewPager时无法做到这一点。至少不是,当您希望您的页面可以刷卡时。

The explaination therefore is very simple:

因此解释非常简单:

When you swipe between two pages, there is a Point when both pages need to be visible, since you cannot swipe between two things when one of those does not even exist at that point.

当您在两个页面之间滑动时,当两个页面都需要可见时会有一个点,因为当其中一个页面之一甚至不存在时,您无法在两个页面之间滑动。

See this question for more: ViewPager.setOffscreenPageLimit(0) doesn't work as expected

有关更多信息,请参阅此问题:ViewPager.setOffscreenPageLimit(0)无法按预期工作

CommonsWare provided a good explaination in the comments of his answer.

CommonsWare在他的回答评论中提供了很好的解释。

#3


11  

but I need to load one page at a time because memory problems.

但我需要一次加载一页因为内存问题。

That presumes that you are getting OutOfMemoryErrors.

这假设您正在获得OutOfMemoryErrors。

Am i going to have to use the old style tabhost etc?

我将不得不使用旧式tabhost等?

Yes, or FragmentTabHost, or action bar tabs.

是,或FragmentTabHost或操作栏选项卡。

or is there a way/hack I can make my viewPager load one page at a time?

或者有没有办法/黑客我可以让我的viewPager一次加载一页?

No, for the simple reason that ViewPager needs more than one page at a time for the sliding animation. You can see this by using a ViewPager and swiping.

不,原因很简单,ViewPager一次需要多个页面来进行滑动动画。您可以使用ViewPager和滑动来查看。

Or, you can work on fixing your perceived memory problems. Assuming this app is the same one that you reported on earlier today, you are only using 7MB of heap space. That will only result in OutOfMemoryErrors if your remaining heap is highly fragmented. There are strategies for memory management (e.g., inBitmap on BitmapOptions for creating bitmaps from external sources) that help address such fragmentation concerns.

或者,您可以修复您感知到的内存问题。假设这个应用程序与您今天早些时候报告的应用程序相同,那么您只使用7MB的堆空间。如果剩余的堆高度碎片化,那只会导致OutOfMemoryErrors。存在用于存储器管理的策略(例如,用于从外部源创建位图的用于BitmapOptions的inBitmap),其有助于解决这种碎片问题。

My Adapter extends BaseAdapter with the ViewHolder patern.

我的适配器使用ViewHolder patern扩展BaseAdapter。

BaseAdapter is for use with AdapterView, not ViewPager.

BaseAdapter用于AdapterView,而不是ViewPager。

#4


0  

You can use FragmentStatePagerAdapter. This allows the pager to hold on to much less memory. It completely removes Fragment instances from the FragmentManager once they are out of reach. The state of the removed Fragments is stored inside the FragmentStatePagerAdapter. The Fragment instance is recreated once you return back to an existing item and the state is restored.

您可以使用FragmentStatePagerAdapter。这允许寻呼机保持更少的内存。一旦它们无法访问,它就会从FragmentManager中完全删除Fragment实例。已删除的Fragments的状态存储在FragmentStatePagerAdapter中。返回到现有项目并恢复状态后,将重新创建Fragment实例。

public static class MyAdapter extends FragmentStatePagerAdapter {
    public MyAdapter(FragmentManager fm) {
        super(fm);
    }

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

    @Override
    public Fragment getItem(int position) {
        return ArrayListFragment.newInstance(position);
    }
}

#5


-1  

I know this is an old post, but I stumbled upon this issue and found a good fix if your loading fragments. Simply, check if the user is seeing the fragment or not by overriding the setUserVisibleHint(). After that load the data.

我知道这是一个旧帖子,但我偶然发现了这个问题,如果你的加载片段发现了一个很好的解决方案。简单地说,通过覆盖setUserVisibleHint()来检查用户是否看到了片段。之后加载数据。

    @Override
public void setUserVisibleHint(boolean isVisibleToUser) {
    super.setUserVisibleHint(isVisibleToUser);
    if (isVisibleToUser) {
        getData(1, getBaseUrl(), getLink());
    }
}

#1


19  

I was having the same problem and I found the solution for it:

我遇到了同样的问题,我找到了解决方案:

Steps:

1) First Download the CustomViewPager Class from this link.

1)首先从此链接下载CustomViewPager类。

2) Use that class as mentioned below:

2)使用如下所述的类:

In Java:

CustomViewPager mViewPager;
mViewPager = (CustomViewPager) findViewById(R.id.swipePager);
mViewPager.setOffscreenPageLimit(0);

In XML:

<com.yourpackagename.CustomViewPager 
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/swipePager"
    android:layout_width="match_parent"
    android:layout_height="match_parent"/>

Now only one page will be loaded at once.

现在只能一次加载一个页面。

#2


14  

As far as I know, that is not possible when using the ViewPager. At least not, when you want your pages to be swipe-able.

据我所知,使用ViewPager时无法做到这一点。至少不是,当您希望您的页面可以刷卡时。

The explaination therefore is very simple:

因此解释非常简单:

When you swipe between two pages, there is a Point when both pages need to be visible, since you cannot swipe between two things when one of those does not even exist at that point.

当您在两个页面之间滑动时,当两个页面都需要可见时会有一个点,因为当其中一个页面之一甚至不存在时,您无法在两个页面之间滑动。

See this question for more: ViewPager.setOffscreenPageLimit(0) doesn't work as expected

有关更多信息,请参阅此问题:ViewPager.setOffscreenPageLimit(0)无法按预期工作

CommonsWare provided a good explaination in the comments of his answer.

CommonsWare在他的回答评论中提供了很好的解释。

#3


11  

but I need to load one page at a time because memory problems.

但我需要一次加载一页因为内存问题。

That presumes that you are getting OutOfMemoryErrors.

这假设您正在获得OutOfMemoryErrors。

Am i going to have to use the old style tabhost etc?

我将不得不使用旧式tabhost等?

Yes, or FragmentTabHost, or action bar tabs.

是,或FragmentTabHost或操作栏选项卡。

or is there a way/hack I can make my viewPager load one page at a time?

或者有没有办法/黑客我可以让我的viewPager一次加载一页?

No, for the simple reason that ViewPager needs more than one page at a time for the sliding animation. You can see this by using a ViewPager and swiping.

不,原因很简单,ViewPager一次需要多个页面来进行滑动动画。您可以使用ViewPager和滑动来查看。

Or, you can work on fixing your perceived memory problems. Assuming this app is the same one that you reported on earlier today, you are only using 7MB of heap space. That will only result in OutOfMemoryErrors if your remaining heap is highly fragmented. There are strategies for memory management (e.g., inBitmap on BitmapOptions for creating bitmaps from external sources) that help address such fragmentation concerns.

或者,您可以修复您感知到的内存问题。假设这个应用程序与您今天早些时候报告的应用程序相同,那么您只使用7MB的堆空间。如果剩余的堆高度碎片化,那只会导致OutOfMemoryErrors。存在用于存储器管理的策略(例如,用于从外部源创建位图的用于BitmapOptions的inBitmap),其有助于解决这种碎片问题。

My Adapter extends BaseAdapter with the ViewHolder patern.

我的适配器使用ViewHolder patern扩展BaseAdapter。

BaseAdapter is for use with AdapterView, not ViewPager.

BaseAdapter用于AdapterView,而不是ViewPager。

#4


0  

You can use FragmentStatePagerAdapter. This allows the pager to hold on to much less memory. It completely removes Fragment instances from the FragmentManager once they are out of reach. The state of the removed Fragments is stored inside the FragmentStatePagerAdapter. The Fragment instance is recreated once you return back to an existing item and the state is restored.

您可以使用FragmentStatePagerAdapter。这允许寻呼机保持更少的内存。一旦它们无法访问,它就会从FragmentManager中完全删除Fragment实例。已删除的Fragments的状态存储在FragmentStatePagerAdapter中。返回到现有项目并恢复状态后,将重新创建Fragment实例。

public static class MyAdapter extends FragmentStatePagerAdapter {
    public MyAdapter(FragmentManager fm) {
        super(fm);
    }

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

    @Override
    public Fragment getItem(int position) {
        return ArrayListFragment.newInstance(position);
    }
}

#5


-1  

I know this is an old post, but I stumbled upon this issue and found a good fix if your loading fragments. Simply, check if the user is seeing the fragment or not by overriding the setUserVisibleHint(). After that load the data.

我知道这是一个旧帖子,但我偶然发现了这个问题,如果你的加载片段发现了一个很好的解决方案。简单地说,通过覆盖setUserVisibleHint()来检查用户是否看到了片段。之后加载数据。

    @Override
public void setUserVisibleHint(boolean isVisibleToUser) {
    super.setUserVisibleHint(isVisibleToUser);
    if (isVisibleToUser) {
        getData(1, getBaseUrl(), getLink());
    }
}