Android ViewPager:在ViewPager中更新屏幕外但缓存的片段

时间:2014-04-17 13:02:52

标签: android caching android-fragments android-viewpager

我有一个ViewPager,它的片段中包含几个TextView,它们有不同的字体大小。 另外,我有增加/减少字体大小的按钮,通过添加其默认大小加上一个名为STEP的值(由inc / dec字体大小按钮更改)来计算每个textView的字体大小。
我的问题是如果在应用大小更改后第一次显示视图,它将在onCreateView()期间创建所需大小的textViews但是如果片段已经缓存并且onCreateView没有再次调用,我不知道如何更新他们的textViews考虑到只有一个缓存的片段在屏幕上显示(我可以毫无问题地更新它)但是其他的不会显示(在这种情况下我不知道它们是否附加到活动)。
换句话说,我如何检测ViewPager缓存了哪些片段及其已调用的onCreateView(这些片段必须应用更新到其视图的片段)。我将它们标记为浅绿色,下面的图片中有问号:enter image description here

3 个答案:

答案 0 :(得分:30)

接受的答案很好,但你不应该缓存所有项目。相反,您可以使用此方法:

mViewPager.setOffscreenPageLimit(int);

例如,有许多项目包含图像和动画。如果您缓存所有这些,这可能会导致OutOfMemoryError。要防止,您可以定义要缓存的页面限制。

修改:而不是HashMap<Integer, Object>,最好使用SparseArray<Object>

答案 1 :(得分:9)

为了通过ViewPager获得缓存项目列表,我更改了我的自定义适配器,扩展名为FragmentStatePagerAdapter:

  1. HashMap<Integer, FragmentDipsplayPageContent> cachedFragmentHashMap添加到我的适配器
  2. 像这样更新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;
    }
    
  3. 像这样更新适配器的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);
    }
    
  4. 添加一个getter来访问来自活动的缓存片段的HashMap:

    public HashMap<Integer, FragmentDipsplayPageContent> getCachedFragmentHashMap() {
        return cachedFragmentHashMap;
    }
    
  5. 在活动中使用此集合进行更新:

    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 :(得分:8)

FragmentStatePagerAdapter适配器

使用FragmentPagerAdapter代替ViewPager