Как заставить мой ViewPager загружать только одну страницу за раз, т.е. setOffscreenPageLimit (0);
Я понимаю, что самое низкое число, которое я могу дать setOffscreenPageLimit(int)
, равно 1. но мне нужно загружать одну страницу за раз, потому что проблемы с памятью.
Мне придется использовать старый стиль tabhost и т.д.? или есть способ/взломать я могу заставить мой viewPager загружать одну страницу за раз?
Мой адаптер расширяет BaseAdapter с помощью патча ViewHolder.
Ответы
Ответ 1
У меня была такая же проблема, и я нашел решение для нее:
Шаги:
1) Сначала загрузите класс CustomViewPager
из по этой ссылке.
2) Используйте этот класс, как указано ниже:
В Java:
CustomViewPager mViewPager;
mViewPager = (CustomViewPager) findViewById(R.id.swipePager);
mViewPager.setOffscreenPageLimit(0);
В 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"/>
Теперь только одна страница будет загружена одновременно.
P.S.: Согласно требованию вопроса, я разместил решение для Viewpager
. Я еще не пробовал то же самое с TabLayout
. Если я найду какое-то решение для этого, я обновлю ответ.
Ответ 2
Насколько я знаю, невозможно при использовании ViewPager. По крайней мере, нет, когда вы хотите, чтобы ваши страницы были удачными.
Поэтому объяснение очень просто:
При прокрутке между двумя страницами есть точка, когда обе страницы должны быть видны, так как вы не можете прокручивать между двумя вещами, когда один из них даже не существует в этой точке. p >
Подробнее см. этот вопрос: ViewPager.setOffscreenPageLimit(0) не работает должным образом
CommonsWare дал хорошее объяснение в комментариях его ответа .
Ответ 3
но мне нужно загрузить одну страницу за раз, потому что проблемы с памятью.
Это предполагает, что вы получаете OutOfMemoryError
s.
Мне придется использовать старый стиль tabhost и т.д.?
Да, или FragmentTabHost
, или вкладки панели действий.
или есть способ/взломать я могу заставить мой viewPager загружать одну страницу за раз?
Нет, по той простой причине, что ViewPager
требуется более одной страницы за раздвижную анимацию. Вы можете увидеть это с помощью ViewPager
и прокрутки.
Или вы можете работать над исправлением проблем, связанных с памятью. Предполагая, что это приложение является тем же о котором вы сообщали ранее,, вы используете только 7 МБ кучного пространства. Это приведет только к OutOfMemoryError
, если ваша оставшаяся куча сильно фрагментирована. Существуют стратегии управления памятью (например, inBitmap
on BitmapOptions
для создания растровых изображений из внешних источников), которые помогают адресовать такие проблемы фрагментации.
Мой адаптер расширяет BaseAdapter с помощью патча ViewHolder.
BaseAdapter
используется для AdapterView
, а не ViewPager
.
Ответ 4
Используя этот метод, вы можете загрузить одну страницу за раз в макете вкладки с помощью пейджера'
.
@Override
public void onResume() {
super.onResume();
if (getUserVisibleHint() && !isVisible) {
Log.e("~~onResume: ", "::onLatestResume");
//your code
}
isVisible = true;
}
@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
super.setUserVisibleHint(isVisibleToUser);
if (isVisibleToUser && isVisible) {
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
@Override
public void run() {
//your code
}
}, 500);
}
}
Ответ 5
Переопределите setUserVisibleHint
и добавьте postDelayed
как postDelayed
ниже в каждом фрагменте.
override fun setUserVisibleHint(isVisibleToUser: Boolean) {
if (isVisibleToUser)
Handler().postDelayed({
if (activity != null) {
// Do you stuff here
}
}, 200)
super.setUserVisibleHint(isVisibleToUser)
}
Теперь я могу справиться с этим, и теперь он отлично работает.
Ответ 6
Сначала скопируйте в SmartFragmentStatePagerAdapter.java, который обеспечивает интеллектуальное кэширование зарегистрированных фрагментов в нашем ViewPager. Это достигается путем переопределения метода instantiateItem() и внутреннего кэширования любых созданных фрагментов. Это решает общую проблему необходимости доступа к текущему элементу в ViewPager.
Теперь мы хотим расшириться от SmartFragmentStatePagerAdapter, скопированного выше, при объявлении нашего адаптера, чтобы мы могли воспользоваться преимуществами лучшего управления памятью на пейджере состояний:
открытый абстрактный класс SmartFragmentStatePagerAdapter extends FragmentStatePagerAdapter { // Разреженный массив для отслеживания зарегистрированных фрагментов в памяти private SparseArray selectedFragments = new SparseArray();
public SmartFragmentStatePagerAdapter(FragmentManager fragmentManager) {
super(fragmentManager);
}
// Register the fragment when the item is instantiated
@Override
public Object instantiateItem(ViewGroup container, int position) {
Fragment fragment = (Fragment) super.instantiateItem(container, position);
registeredFragments.put(position, fragment);
return fragment;
}
// Unregister when the item is inactive
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
registeredFragments.remove(position);
super.destroyItem(container, position, object);
}
// Returns the fragment for the position (if instantiated)
public Fragment getRegisteredFragment(int position) {
return registeredFragments.get(position);
}
}
//Расширяем из SmartFragmentStatePagerAdapter теперь вместо этого для более динамичных элементов ViewPager открытый статический класс MyPagerAdapter extends SmartFragmentStatePagerAdapter { private static int NUM_ITEMS = 3;
public MyPagerAdapter(FragmentManager fragmentManager) {
super(fragmentManager);
}
// Returns total number of pages
@Override
public int getCount() {
return NUM_ITEMS;
}
// Returns the fragment to display for that page
@Override
public Fragment getItem(int position) {
switch (position) {
case 0: // Fragment # 0 - This will show FirstFragment
return FirstFragment.newInstance(0, "Page # 1");
case 1: // Fragment # 0 - This will show FirstFragment different title
return FirstFragment.newInstance(1, "Page # 2");
case 2: // Fragment # 1 - This will show SecondFragment
return SecondFragment.newInstance(2, "Page # 3");
default:
return null;
}
}
// Returns the page title for the top indicator
@Override
public CharSequence getPageTitle(int position) {
return "Page " + position;
}
}
Ответ 7
Вы можете использовать FragmentStatePagerAdapter. Это позволяет пейджеру удерживать гораздо меньше памяти. Он полностью удаляет экземпляры фрагментов из FragmentManager, когда они недоступны. Состояние удаленных фрагментов сохраняется внутри 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);
}
}
Ответ 8
Я знаю, что это старый пост, но я наткнулся на эту проблему и нашел хорошее исправление, если вы загружаете фрагменты. Просто проверьте, видит ли пользователь фрагмент или нет, переопределяя setUserVisibleHint(). После этого загрузите данные.
@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
super.setUserVisibleHint(isVisibleToUser);
if (isVisibleToUser) {
getData(1, getBaseUrl(), getLink());
}
}