Как заставить мой 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());
    }
}