Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android ViewPager: Update off-screen but cached fragments in ViewPager

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

like image 999
VSB Avatar asked Apr 17 '14 13:04

VSB


People also ask

How do I update my Android ViewPager adapter?

Firstly set viewpager adapter to null then recreate the adapter and set i to it to viewpager. Show activity on this post. Define which message which is needed to update. Write below code in the Fragment which is needed update.

How do I refresh ViewPager fragments?

Using the ViewPager. OnPageChangeListener is the correct way to go, but you will need to refactor your adapter a bit in order to keep a reference to each Fragment contained in the FragmentPagerAdapter. Then, instead of creating a new Fragment, use the one contained in the adapter: mViewPager.

Can I use ViewPager with views not with fragments?

yes...you can use View instead of Fragment in viewpager.

Is ViewPager deprecated?

This method may be called by the ViewPager to obtain a title string to describe the specified page. This method is deprecated. This method should be called by the application if the data backing this adapter has changed and associated views should update.


3 Answers

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>.

like image 54
slhddn Avatar answered Sep 19 '22 23:09

slhddn


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.

like image 44
VSB Avatar answered Sep 20 '22 23:09

VSB


Use FragmentStatePagerAdapter instead of FragmentPagerAdapter for your ViewPager Adapter

like image 7
naran z Avatar answered Sep 17 '22 23:09

naran z