Ответ 1
Требуется ли ViewPager минимум 1 внеэкранных страниц
Да. Если я правильно читаю исходный код, вы должны получить предупреждение об этом в LogCat, например:
Requested offscreen page limit 0 too small; defaulting to 1
Фрагменты, которые я использую в моем экземпляре ViewPager
, довольно ресурсоемкие, поэтому я хотел бы только загружать их по одному. Когда я попробую следующее:
mViewPager.setOffscreenPageLimit(0);
mViewPager.setAdapter(mPagerAdapter);
Функция переопределения My FragmentStatePagerAdapter.getItem(int position)
называется 3 раза, что и происходит при вызове mViewPager.setOffscreenPageLimit(1)
. Я бы ожидал, что его можно будет вызывать только один раз, потому что я указал 0 на экранных страницах.
Я считаю, что я правильно звоню, потому что, если я звоню mViewPager.setOffscreenPageLimit(2)
, FragmentStatePagerAdapter.getItem(int position)
вызывается 5 раз, как я ожидал.
Требуется ли ViewPager минимум 1 внеэкранных страниц, или я делаю что-то неправильно здесь?
Требуется ли ViewPager минимум 1 внеэкранных страниц
Да. Если я правильно читаю исходный код, вы должны получить предупреждение об этом в LogCat, например:
Requested offscreen page limit 0 too small; defaulting to 1
Лучший способ, который я нашел, - setUserVisibleHint
добавьте это в свой фрагмент
@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
super.setUserVisibleHint(isVisibleToUser);
if (isVisibleToUser) {
// load data here
}else{
// fragment is no longer visible
}
}
Первое добавление
boolean _areLecturesLoaded = false;
чем
@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
super.setUserVisibleHint(isVisibleToUser);
if (isVisibleToUser && !_areLecturesLoaded) {
//Load Your Data Here like.... new GetContacts().execute();
_areLecturesLoaded = true;
}
else{
}
}
Вы можете попробовать следующее:
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(){}
Альтернативное решение использует FragmentStatePagerAdapter
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);
}
}
ViewPager по умолчанию загружает следующую страницу (фрагмент), которую вы не можете изменить с помощью setOffscreenPageLimit (0). Но вы можете сделать что-то, чтобы взломать. Вы можете реализовать функцию onPageSelected в Activity, содержащей ViewPager. В следующем фрагменте (который вы не хотите загружать) вы пишете функцию let say showContent(), где вы вставляете весь код инициализации ресурсов и ничего не делаете перед методом onResume(). Затем вызовите функцию showViewContent() внутри onPageSelected. Надеюсь, это поможет.
для функции "instantiateItem", просто подготовьте фрагмент, но не загружайте тяжелое содержимое.
Используйте "onPageChangeListener", чтобы каждый раз, когда вы переходите на определенную страницу, вы загружаете ее тяжелый контент и показываете его.
Это может быть старый поток, но это, похоже, работает для меня. Переопределите эту функцию:
@Override
public void setMenuVisibility(boolean menuVisible) {
super.setMenuVisibility(menuVisible);
if ( menuVisible ) {
/**
* Load your stuffs here.
*/
} else {
/**
* Fragment not currently Visible.
*/
}
}
счастливые кодировки...
У меня такая же проблема. Я нашел полезный код на этом сайте и преобразовал его.
min int для mViewPager.setOffscreenPageLimit(...); 1, поэтому, даже если вы измените его на 0, вы все равно загрузите 2 страницы.
Первое, что нужно сделать, это создать статический int, который мы назовем maxPageCount и переопределим метод getCount() для FragmentStatePagerAdapter для возврата maxPageCount:
@Override
public int getCount() {
return maxPageCount;
}
Создайте статический метод, доступный из любого места в программе, которое позволит вам изменить этот maxCount:
public static void addPage(){
maxPageCount++; //or maxPageCount = fragmentPosition+2
mFragmentStatePagerAdapter.notifyDataSetChanged(); //notifyDataSetChanged is important here.
}
Теперь инициализируйте maxPageCount до 1. Когда вы захотите, вы можете добавить еще одну страницу. В моем случае, когда мне нужен был пользователь для обработки текущей страницы, прежде чем сгенерировать другую. Он делает это, а затем без проблем может перейти на следующую страницу.
Надеюсь, что это поможет кому-то.