Android FragmentPagerAdapter数据刷新notifyDataSetChanged没效果研究

android3.0之后提出fragment概念正逐渐取代tabhost的地位,support-v4包也提供了很好使用的viewpager类。不多说。了解过fragment之后你会发现比tabhost好用许多,并且viewpager也支持fragment的嵌入,这使得项目的模块化耦合度大大降低,项目中使用ViewPager+Fragment实现tab分页+子tab页内容滑动效果
效果图如下:
Android <wbr>FragmentPagerAdapter数据刷新notifyDataSetChanged没效果研究
点击个个tab1更换pageadapter的值实现数据的更新。通过继承fragmentpageadpater你会发现使用起来很方便。具体fragmentpageradapter怎么用?网上很多看客可以去搜一下。
下面我就要说到本文的核心当你更新里fragmentList集合后调用fragmentpageadpater的notifyDataSetChanged方法时发现数据根本就没有刷新。网络上会提到pageadapter的刷新方案如下代码:
  复写pageradapter的 getItemPosition方法设置tag为 POSITION_NONE意思是没有找到child要求重新加载。
@Override  
public int getItemPosition(Object object) { 
   return POSITION_NONE; 
}  
结果你发现是刷新了一下但内容还是原始的数据。通过对fragmentpageadapter的源码查看你会在instantiateItem方法里面发现这一段
  // Do we already have thisfragment?
       String name =makeFragmentName(container.getId(), position);
       Fragment fragment =mFragmentManager.findFragmentByTag(name);
       if (fragment != null) {
           if (DEBUG)Log.v(TAG, "Attaching item #" + position + ": f=" +fragment);
          mCurTransaction.attach(fragment);
       } else {
           fragment =getItem(position);
           if (DEBUG)Log.v(TAG, "Adding item #" + position + ": f=" +fragment);
          mCurTransaction.add(container.getId(), fragment,
                 makeFragmentName(container.getId(),position));
       }
原来他会先去 FragmentManager里面去查找有没有相关的fragment如果有就直接使用如果没有才会触发fragmentpageadapter的getItem方法获取一个fragment。所以你更新的fragmentList集合是没有作用的,还要清除 FragmentManager里面缓存的fragment。解决办法:在继承的fragmentpageadapter类里面添加这么一个方法

public voidsetFragments(ArrayList fragments) {
   if(this.fragments !=null){
     FragmentTransaction ft = fm.beginTransaction();
     for(Fragment f:this.fragments){
       ft.remove(f);
     }
     ft.commit();
     ft=null;
     fm.executePendingTransactions();
   }
  this.fragments = fragments;
  notifyDataSetChanged();
}
就能完美的解决fragmentpageadapter数据刷新。


代码:
/**
 * Copyright @ jxl
 */
package com.hortor.officecloud.ui;

import java.util.ArrayList;

import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.app.FragmentTransaction;

/**
 * @author kingjxl2006@126.com
 * @since 2012-10-16 上午11:18:21
 */
public class FragmentVPAdapter extends FragmentPagerAdapter {
    private ArrayList<Fragment> fragments;
    private FragmentManager fm;
    public FragmentVPAdapter(FragmentManager fm, ArrayList<Fragment> fragments) {
        super(fm);
        this.fm = fm;
        this.fragments = fragments;
    }
    
    public void setFragments(ArrayList<Fragment> fragments) {
        if(this.fragments != null){
            FragmentTransaction ft = fm.beginTransaction();
            for(Fragment f:this.fragments){
                ft.remove(f);
            }
            ft.commit();
            ft=null;
            fm.executePendingTransactions();
        }
        this.fragments = fragments;
        notifyDataSetChanged();
    }
    
    @Override  
    public int getItemPosition(Object object) {  
        return POSITION_NONE;  
    }  

    @Override
    public Fragment getItem(int arg0) {
        return fragments.get(arg0);
    }

    @Override
    public int getCount() {
        return fragments.size();
    }
}


另一篇文章:
很多人在网上说ViewPager的PagerAdapter.notifyDataSetChanged()无效。刚开始我也这样认为,甚至被误导以为是真理。
  后来,找了一下,在PagerAdatpar重写getItemPosition(),return  POSITION_NONE即可每次刷新加载图面。这是关键点。
  这时,如果只是修改"DataSet",如List等这类的,然后再 notifyDataSetChanged(),会发现出现界面重叠。解决办法是重写destroyItem(),把ViewGroup强转为ViewPager,Object强转为View。最后ViewGroup.removeView()即可。


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值