У меня есть ViewPager, который содержит несколько TextView внутри его фрагмента, который имеет разные размеры шрифта.
Кроме того, у меня есть кнопки для увеличения/уменьшения размера шрифта, которые вычисляют размер шрифта каждого textView, добавляя его размер по умолчанию плюс значение, называемое STEP (которое изменяется кнопкой включения/уменьшения размера шрифта).
Моя проблема в том, что если представление отображается в первый раз после применения изменений размера, оно создаст текстовые элементы в желаемом размере во время onCreateView(), однако, если фрагмент уже кэширован, а onCreateView снова не вызван, я не знаю, как обновлять их текстовые элементы если на экране отображается только один из кешированных фрагментов (и я могу без проблем обновить его), но другие не отображаются (я не знаю, прикреплены ли они к активности или нет в этом случае).
Другими словами, как я могу определить, какие фрагменты кэшируются ViewPager и их уже вызванный onCreateView (это фрагменты, которые обновляют их представления, должны применяться). Я отметил их светло-зеленым цветом с вопросительными знаками ниже:
Android ViewPager: обновление за пределами экрана, но кэшированных фрагментов в ViewPager
Ответ 1
Чтобы иметь список кешированных элементов ViewPager, я изменил свой пользовательский адаптер, который расширяет FragmentStatePagerAdapter:
- Добавить
HashMap<Integer, FragmentDipsplayPageContent> cachedFragmentHashMap
в мой адаптер -
Обновить метод getItem(), подобный этому
public Fragment getItem(int index) { Fragment fragment = new FragmentDipsplayPageContent(); Bundle args = new Bundle(); args.putInt("INDEX", index); fragment.setArguments(args); cachedFragmentHashMap.put(index,fragment); return fragment; }
-
Обновите метод destroyItem() адаптера, подобный этому
@Override public void destroyItem(ViewGroup container, int position, Object object) { super.destroyItem(container, position, object); //add this line to remove fragments wiped from ViewPager cache cachedFragmentHashMap.remove(position); }
-
Добавьте получателя для доступа к HashMap кешированных фрагментов из активности:
public HashMap<Integer, FragmentDipsplayPageContent> getCachedFragmentHashMap() { return cachedFragmentHashMap; }
-
обновление с использованием этой коллекции внутри деятельности:
private void increaseFontSizeForCachedFragments() { HashMap<Integer, FragmentDipsplayPageContent> cachedFragmentsHashMap = adapterViewPager .getCachedFragmentHashMap(); Collection<FragmentDipsplayPageContent> fragmentsCollection = cachedFragmentsHashMap .values(); for (FragmentDipsplayPageContent fragmentDipsplayPageContent : fragmentsCollection) { //update views of fragment fragmentDipsplayPageContent.increasTextFontSize(); } }
Таким образом обновляются все кэшированные фрагменты, включая видимые и внеэкранные фрагменты.
Ответ 2
Принятый ответ хорош, но вы не должны кэшировать все элементы. Вместо этого вы можете использовать этот метод:
mViewPager.setOffscreenPageLimit(int);
Например, существует много объектов с изображением и анимацией. Если вы их кешируете, это, вероятно, приведет к OutOfMemoryError
. Чтобы предотвратить, вы можете определить ограничение страницы для кеширования.
Изменить: вместо HashMap<Integer, Object>
лучше использовать SparseArray<Object>
.
Ответ 3
Используйте FragmentStatePagerAdapter
вместо FragmentPagerAdapter
для вашего адаптера ViewPager