Android ViewPager: обновление за пределами экрана, но кэшированных фрагментов в ViewPager

У меня есть ViewPager, который содержит несколько TextView внутри его фрагмента, который имеет разные размеры шрифта. Кроме того, у меня есть кнопки для увеличения/уменьшения размера шрифта, которые вычисляют размер шрифта каждого textView, добавляя его размер по умолчанию плюс значение, называемое STEP (которое изменяется кнопкой включения/уменьшения размера шрифта).
Моя проблема в том, что если представление отображается в первый раз после применения изменений размера, оно создаст текстовые элементы в желаемом размере во время onCreateView(), однако, если фрагмент уже кэширован, а onCreateView снова не вызван, я не знаю, как обновлять их текстовые элементы если на экране отображается только один из кешированных фрагментов (и я могу без проблем обновить его), но другие не отображаются (я не знаю, прикреплены ли они к активности или нет в этом случае).
Другими словами, как я могу определить, какие фрагменты кэшируются ViewPager и их уже вызванный onCreateView (это фрагменты, которые обновляют их представления, должны применяться). Я отметил их светло-зеленым цветом с вопросительными знаками ниже: enter image description here

Ответ 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