Refresh images on FragmentStatePagerAdapter on resuming activity

前端 未结 4 1206
离开以前
离开以前 2020-12-09 16:47

I have created an activity that uses FragmentStatePagerAdapter to provide small gallery. However, I can\'t get it to refresh when activity resumes (after coming

相关标签:
4条回答
  • 2020-12-09 17:23

    I was having a similar problem like your, after some research i created a nice script that avoid recreating fragments that are already there but at the same time allow you to update all visible/initiated fragment.

    import android.support.v4.app.Fragment;
    import android.support.v4.app.FragmentManager;
    import android.support.v4.app.FragmentStatePagerAdapter;
    import android.view.ViewGroup;
    
    import java.util.WeakHashMap;
    
    /**
     * Created by TheCobra on 9/17/15.
     */
    public abstract class FragmentAdvanceStatePagerAdapter extends FragmentStatePagerAdapter
    {
        private WeakHashMap<Integer, Fragment> mFragments;
    
        public FragmentAdvanceStatePagerAdapter(FragmentManager fm)
        {
            super(fm);
            mFragments = new WeakHashMap<Integer, Fragment>();
        }
    
        @Override
        public Fragment getItem(int position)
        {
            Fragment item = getFragmentItem(position);
            mFragments.put(Integer.valueOf(position), item);
            return item;
        }
    
        @Override
        public void destroyItem(ViewGroup container, int position, Object object)
        {
            super.destroyItem(container, position, object);
            Integer key = Integer.valueOf(position);
            if (mFragments.containsKey(key))
            {
                mFragments.remove(key);
            }
        }
    
        @Override
        public void notifyDataSetChanged()
        {
            super.notifyDataSetChanged();
            for (Integer position : mFragments.keySet())
            {
                //Make sure we only update fragments that should be seen
                if (position != null && mFragments.get(position) != null && position.intValue() < getCount())
                {
                    updateFragmentItem(position, mFragments.get(position));
                }
            }
        }
    
        @Override
        public int getItemPosition(Object object)
        {
            //If the object is a fragment, check to see if we have it in the hashmap
            if (object instanceof Fragment)
            {
                int position = findFragmentPositionHashMap((Fragment) object);
                //If fragment found in the hashmap check if it should be shown
                if (position >= 0)
                {
                    //Return POSITION_NONE if it shouldn't be display
                    return (position >= getCount()? POSITION_NONE : position);
                }
            }
    
            return super.getItemPosition(object);
        }
    
        /**
         * Find the location of a fragment in the hashmap if it being view
         * @param object the Fragment we want to check for
         * @return the position if found else -1
         */
        protected int findFragmentPositionHashMap(Fragment object)
        {
            for (Integer position : mFragments.keySet())
            {
                if (position != null &&
                    mFragments.get(position) != null &&
                    mFragments.get(position) == object)
                {
                    return position;
                }
            }
    
            return -1;
        }
    
        public abstract Fragment getFragmentItem(int position);
        public abstract void updateFragmentItem(int position, Fragment fragment);
    }
    

    Copy that code into a file name "FragmentAdvanceStatePagerAdapter.java". Now in your adapter, extend from this one and override "getFragmentItem()" & "updateFragmentItem()". Whenever you call notifydatachange(), updateFragmentItem() will be called with all the fragment already created. When the adapter need to create a new fragment, getFragmentItem() will be called.

    I hope that save and help a lot of people :)

    Good Luck and happy Programming!!!

    P.S. your adapter "getItem()" should be "getFragmentItem()" if you use this class.

    0 讨论(0)
  • 2020-12-09 17:24

    Never just use POSITION_NONE use

    if(fragmentManager.getFragments().contains(object))
        return POSITION_NONE;
    else
        return POSITION_UNCHANGED;
    

    to avoid Fatal Exception: java.lang.IllegalStateException Fragment {} is not currently in the FragmentManager

    0 讨论(0)
  • 2020-12-09 17:26

    Dealing with fragment pager adapters can be a PITA.

    Here are a few helpful tips:

    ViewPager PagerAdapter not updating the View

    Update ViewPager dynamically?

    Generally speaking this one works 99% of the time...

    Override getItemPosition in your PagerAdapter like this:

    @Override
    public int getItemPosition(Object object) {
        return POSITION_NONE;
    }
    

    Sometimes even those don't work, I have to use the 'brute force' method and recreate the entire view again (from onCreate onwards)...

    0 讨论(0)
  • 2020-12-09 17:48

    Instead of returning POSITION_NONE and creating all fragments again, you can do as I suggested here: Update ViewPager dynamically?

    0 讨论(0)
提交回复
热议问题