java ViewPager.setOffscreenPageLimit(0) 根本没有效果。如何在 ViewPager 中一次只加载一个页面?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/17948681/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
ViewPager.setOffscreenPageLimit(0) has no effect at all. How do I only load one page at a time in a ViewPager?
提问by code511788465541441
even when I set oViewPager.setOffscreenPageLimit(0) my view pager still loads 1 off screen page on each side of the visible page.
即使我设置 oViewPager.setOffscreenPageLimit(0) 我的视图寻呼机仍然在可见页面的每一侧加载 1 个离屏页面。
How do I make it only load the page when the user slides to it?
如何让它只在用户滑动到页面时加载页面?
My adapter if it helps:
我的适配器是否有帮助:
public class MainPagerAdapter extends FragmentPagerAdapter {
protected static final String[] CONTENT = new String[] { "page 1", "page 2", "page 3", "page 4", };
private int mCount = CONTENT.length;
public MainPagerAdapter(FragmentManager fm) {
super(fm);
}
@Override
public Fragment getItem(int position) {
//return TestFragment.newInstance(CONTENT[position % CONTENT.length]);
return MainFragment.newInstance(position);
}
@Override
public int getCount() {
return mCount;
}
@Override
public CharSequence getPageTitle(int position) {
return MainPagerAdapter.CONTENT[position % CONTENT.length];
}
public void setCount(int count) {
if (count > 0 && count <= 10) {
mCount = count;
notifyDataSetChanged();
}
}
}
回答by edthethird
Another alternative is to use a OnPageChangeListener
, and whenever a page change occurs call a refresh method in your fragments.
另一种选择是使用OnPageChangeListener
, 并且每当发生页面更改时调用片段中的刷新方法。
This will require you to set a higher OffScreenPageLimit
, but the fragments will be updated every time one is brought into view.
这将需要您设置更高的OffScreenPageLimit
,但是每次看到片段时都会更新片段。
pager.setOnPageChangeListener(new OnPageChangeListener() {
@Override
public void onPageSelected(int position){
((MyRefreshableFragment)pager.getAdapter().getItem(position)).refresh();
}
@Override
public void onPageScrolled(int arg0, float arg1, int arg2) {}
@Override
public void onPageScrollStateChanged(int arg0) {}
});
回答by CommonsWare
How do I make it only load the page when the user slides to it?
如何让它只在用户滑动到页面时加载页面?
Write your own ViewPager
. As is noted by Jani's answer, ViewPager
has a minimum offscreen page limit of 1 to each side.
自己写ViewPager
。正如 Jani 的回答所指出的,ViewPager
每边的最小屏幕外页面限制为 1。
This is required for the swiping animation to work smoothly. Otherwise, if we had to wait for you to set up the UI for the next page, the user's swipe would be frozen, or swipe to blank content, for however long it takes you to get that UI established.
这是滑动动画顺利工作所必需的。否则,如果我们不得不等待您为下一页设置 UI,则用户的滑动将被冻结,或者滑动到空白内容,无论您需要多长时间才能建立该 UI。
回答by Keshav Gera
add this method in fragment
在片段中添加此方法
@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
super.setUserVisibleHint(isVisibleToUser);
if (isVisibleToUser) {
// load data here resumePlayer();
}else{
// fragment is no longer visible pausePlayer();
}
}
回答by Random Guy
I know this is very late answer but for God's sake you do not have to write your own viewpager as someone suggested.
我知道这是一个很晚的答案,但看在上帝的份上,您不必像有人建议的那样编写自己的 viewpager。
Lets take things from start:
让我们从头开始:
How viewpager works:
查看页面的工作原理:
By default it keeps one item in memory either side so it does not have to create it everytime.
默认情况下,它在内存的任一侧保留一个项目,因此不必每次都创建它。
1st Solution:
第一个解决方案:
mViewPager.setOffscreenPageLimit(0);
which results to:
结果是:
Requested offscreen page limit 0 too small; defaulting to 1
请求的屏幕外页面限制 0 太小;默认为 1
2nd Solution:
第二种解决方案:
You want to update the Fragment when it is actually visible to the user so use the method:
您想在用户实际可见时更新 Fragment,因此请使用以下方法:
@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
super.setUserVisibleHint(isVisibleToUser);
if (isVisibleToUser) {
//Do something like
//adapter.notifyDataSetChanged();
}
}
Hope it helps someone in the future!!!
希望对未来的人有所帮助!!!
回答by Dante
回答by Jani Bela
You cant do this. You will get an error like: "Requested offscreen page limit 0 too small; defaulting to 1". But here you can find more about it: ViewPager.setOffscreenPageLimit(0) doesn't work as expected
你不能这样做。您将收到如下错误:“请求的屏幕外页面限制 0 太小;默认为 1”。但在这里你可以找到更多关于它的信息:ViewPager.setOffscreenPageLimit(0) 不按预期工作
回答by Yuhan Zhang
there are the source code
有源代码
/**
* Set the number of pages that should be retained to either side of the
* current page in the view hierarchy in an idle state. Pages beyond this
* limit will be recreated from the adapter when needed.
*
* <p>This is offered as an optimization. If you know in advance the number
* of pages you will need to support or have lazy-loading mechanisms in place
* on your pages, tweaking this setting can have benefits in perceived smoothness
* of paging animations and interaction. If you have a small number of pages (3-4)
* that you can keep active all at once, less time will be spent in layout for
* newly created view subtrees as the user pages back and forth.</p>
*
* <p>You should keep this limit low, especially if your pages have complex layouts.
* This setting defaults to 1.</p>
*
* @param limit How many pages will be kept offscreen in an idle state.
*/
public void setOffscreenPageLimit(int limit) {
if (limit < DEFAULT_OFFSCREEN_PAGES) {//DEFAULT_OFFSCREEN_PAGES = 1
Log.w(TAG, "Requested offscreen page limit " + limit + " too small; defaulting to " +
DEFAULT_OFFSCREEN_PAGES);
limit = DEFAULT_OFFSCREEN_PAGES;
}
if (limit != mOffscreenPageLimit) {
mOffscreenPageLimit = limit;
populate();
}
}
you can custom your viewpager by copy the viewpager's source, then change this method
您可以通过复制 viewpager 的源来自定义您的 viewpager,然后更改此方法
like this
像这样
public class LazyViewPager extends ViewGroup {
private static final String TAG = "LazyViewPager";
private static final boolean DEBUG = false;
private static final boolean USE_CACHE = false;
private static final int DEFAULT_OFFSCREEN_PAGES = 0;//change default to load one page,no offset,ViewPager is 1,so cache 2 Fragment
private static final int MAX_SETTLE_DURATION = 600; // ms
回答by Dulanga
I found a solution for this after few work round. This is work perfectly. each tab fragment class implement this code steps.
经过几次工作后,我找到了解决方案。这是完美的工作。每个选项卡片段类实现此代码步骤。
private boolean loadData = false;
@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
super.setUserVisibleHint(isVisibleToUser);
if (this.isVisible() && isVisibleToUser ) {
loadData = true;
// Load your data or call web services
performDataRequestAsyncTask();
}
}
and In onCreateView Load same data or call same web service like below
并在 onCreateView 加载相同的数据或调用相同的 Web 服务,如下所示
if(!loadData && YourMainFragment.yourMainFragment.getCurrentTab() == CURRENT_TAB_INDEX){
// Load your data or call web services
performDataRequestAsyncTask();
}
In YourMainFragment which you initialize your viewrpage add this method to get currentTab
在您初始化视图页面的 YourMainFragment 中,添加此方法以获取 currentTab
public int getCurrentTab(){
if(mViewPager != null) return mViewPager.getCurrentItem();
else return -1;
}