Android ViewPager: Update off-screen but cached fr

2019-02-04 17:20发布

I have a ViewPager which contains several TextViews inside its fragment which they have different font sizes. In addition, I got buttons for increase/decreasing font size which calculate font size of each textView by adding its default size plus a value called STEP (which changes by inc/dec font size button).
My problem is if a view is displayed for first time after applying size changes, It will create textViews in desired size during onCreateView() however if fragment was cached already and onCreateView is not called again, I don't know how to update their textViews considering only one of cached fragments is displaying on screen (and i can update it with no problem) but others are not displayed (I don't know if they are attached to activity or not in this case).
In other words how can i detect which fragments are cached by ViewPager and their onCreateView already called (these are fragments which update to their views must be applied). I marked them in light green with question marks in below picture: enter image description here

3条回答
在下西门庆
2楼-- · 2019-02-04 17:42

In order to have a list of cached items by ViewPager I changed my Custom Adapter which an extension FragmentStatePagerAdapter:

  1. Add a HashMap<Integer, FragmentDipsplayPageContent> cachedFragmentHashMap to my adapter
  2. Update getItem() method like this

    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;
    }
    
  3. Update destroyItem() method of adapter like this

    @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);
    }
    
  4. Add a getter to access HashMap of cached Fragments from activity:

    public HashMap<Integer, FragmentDipsplayPageContent> getCachedFragmentHashMap() {
        return cachedFragmentHashMap;
    }
    
  5. update using this collection inside activity:

    private void increaseFontSizeForCachedFragments() {
        HashMap<Integer, FragmentDipsplayPageContent> cachedFragmentsHashMap = adapterViewPager
                .getCachedFragmentHashMap();
        Collection<FragmentDipsplayPageContent> fragmentsCollection = cachedFragmentsHashMap
                .values();
        for (FragmentDipsplayPageContent fragmentDipsplayPageContent : fragmentsCollection) {
            //update views of fragment
            fragmentDipsplayPageContent.increasTextFontSize();
        }
    }
    


    This way all cached fragments including visible and off-screen fragments are updated.

查看更多
家丑人穷心不美
3楼-- · 2019-02-04 17:45

Accepted answer is nice but you shouldn't cache all the items. Instead, you can use this method:

mViewPager.setOffscreenPageLimit(int);

For example, there are many many items with image and animations. If you cache all of them, this probably will result with an OutOfMemoryError. To prevent, you can define page limit to be cached.

Edit: Instead HashMap<Integer, Object>, it is better to use SparseArray<Object>.

查看更多
放我归山
4楼-- · 2019-02-04 17:48

Use FragmentStatePagerAdapter instead of FragmentPagerAdapter for your ViewPager Adapter

查看更多
登录 后发表回答