1.最近做需求,遇到一个问题,一个Fragment中包含了一个ViewPager,viewPager中包含一adapter ,adapter中包含了4个Fragment。想要动态替换第3个Fragment由A Fragment--》B Fragment。如图:

2. 原本以为很简单的事,分分钟就能搞定,但是更新了list<Fragment> 数据源,notifyDataSetChanged()后,页面没有被替换,邪门啊。

3.上网一通乱查,发现一个说法:重写getItemPosition()方法返回POSITION_NONE 进行刷新。于是乎,查了下源码,大致刷新的过程,如图:

4.流程知道了,具体怎么实现呢。从无到有是最难的,还是参考下系统类吧:FragmentPagerAdapter ,把它重写。见代码

public class TabFragmentAdapter extends PagerAdapter {
private static final String TAG = "FragmentPagerAdapter";
private static final boolean DEBUG = false; private FragmentManager mFragmentManager;
private FragmentTransaction mCurTransaction = null;
private Fragment mCurrentPrimaryItem = null; private boolean isRefesh = false;
ArrayList<Fragment> list = new ArrayList<>();
//刷新对象的接口
public interface RefeshFragment{ } public boolean isRefesh(Object object) {
if (isRefesh && (object instanceof RefeshFragment)) {
return true;
} else {
return false;
}
} public void setRefesh(boolean t) {
isRefesh = t;
} public TabFragmentAdapter(FragmentManager fm) {
mFragmentManager = fm;
} public void setFragments(ArrayList fragments) {
if (this.list != null) {
this.list = fragments;
}
} public Fragment getItem(int position) {
return list.get(position);
} @Override
public int getCount() {
return list == null ? 0 : list.size();
} @SuppressWarnings("ReferenceEquality")
@Override
public Object instantiateItem(ViewGroup container, int position) {
if (mCurTransaction == null) {
mCurTransaction = mFragmentManager.beginTransaction();
} final long itemId = getItemId(position); String name = makeFragmentName(container.getId(), itemId);
Fragment fragment = mFragmentManager.findFragmentByTag(name);
if (fragment != null && !(isRefesh(fragment))) {
if (DEBUG) Log.v(TAG, "Attaching item #" + itemId + ": f=" + fragment);
mCurTransaction.attach(fragment);
} else {
fragment = getItem(position);
if (DEBUG) Log.v(TAG, "Adding item #" + itemId + ": f=" + fragment);
mCurTransaction.add(container.getId(), fragment, makeFragmentName(container.getId(), itemId));
}
if (fragment != mCurrentPrimaryItem) {
fragment.setMenuVisibility(false);
fragment.setUserVisibleHint(false);
} if (isRefesh(fragment)) {
isRefesh = false;
}
return fragment;
} @Override
public void destroyItem(ViewGroup container, int position, Object object) {
if (mCurTransaction == null || isRefesh(object)) {//避免缓存指令的干扰 每次使用新的 BackStackRecord 对象
mCurTransaction = mFragmentManager.beginTransaction();
}
if (DEBUG)
Log.v(TAG, "Detaching item #" + getItemId(position) + ": f=" + object + " v=" + ((Fragment) object).getView());
if (isRefesh(object)) {
mCurTransaction.remove((Fragment) object);
} else {
mCurTransaction.detach((Fragment) object);
}
} @SuppressWarnings("ReferenceEquality")
@Override
public void setPrimaryItem(ViewGroup container, int position, Object object) {
Fragment fragment = (Fragment) object;
if (fragment != mCurrentPrimaryItem) {
if (mCurrentPrimaryItem != null) {
mCurrentPrimaryItem.setMenuVisibility(false);
mCurrentPrimaryItem.setUserVisibleHint(false);
}
if (fragment != null) {
fragment.setMenuVisibility(true);
fragment.setUserVisibleHint(true);
}
mCurrentPrimaryItem = fragment;
}
} @Override
public void finishUpdate(ViewGroup container) {
if (mCurTransaction != null) {
mCurTransaction.commitAllowingStateLoss();
mCurTransaction = null;
}
} @Override
public boolean isViewFromObject(View view, Object object) {
return ((Fragment) object).getView() == view;
} @Override
public Parcelable saveState() {
return null;
} @Override
public void restoreState(Parcelable state, ClassLoader loader) {
} public long getItemId(int position) {
return position;
} private static String makeFragmentName(int viewId, long id) {
return "android:switcher:" + viewId + ":" + id;
} @Override
public int getItemPosition(Object object) {
if (isRefesh(object)) {//是否进行销毁
return POSITION_NONE;
} else {
return POSITION_UNCHANGED;
} }
}

5.说明:

a.你要替换的Fragment需要先实现空接口RefeshFragmnet,用来表明你是需要被替换的。

b.调用时

           mFragmentList.set(FRAGMENT_STOCKS,new StocksFragment());//替换数据源
adapter.setRefesh(true);//设置刷新标识
adapter.notifyDataSetChanged();//通知adapter刷新

6.小结:其实adapter的源码挺简单的,viewPager比较复杂。只要有耐心,跟着源码debug,为之,则难者亦易矣。上边的代码要是有不懂的地方可以在下方留言或者debug一下

动态更新ViewPager中的Fragment(替换Fragment)的更多相关文章

  1. postgresql 存储过程动态更新数据

    -- 目标:动态更新表中数据 -- 老规矩上代码-----------------------------tablename 表名--feildname 字段名数组--feildvalue 字段值数组 ...

  2. viewpager中彻底性动态添加、删除Fragment

    为了解决彻底删除fragment,我们要做的是:1.将FragmentPagerAdapter 替换成FragmentStatePagerAdapter,因为前者只要加载过,fragment中的视图就 ...

  3. Fragment碎片的创建和动态更新

    Fragment,在平板应用中较为参见,把视图分为两个甚至多个模块. 一,一个简单的fragment 1.创建两个局部文件,用于等待被调用 (1)left_fragment (2)right_frag ...

  4. Fragment生命周期及在viewpager中的生命周期

    简介 本篇博客主要从一下三个方面介绍fragement的生命周期 1.fragment的生命周期及与Activity的生命周期的比较 2.FrameLayou布局添加.替换Fragment时fragm ...

  5. 友盟页面统计 - 关于Viewpager中的Fragment的生命周期

    Activity和Fragment各自理论上的生命周期 Activity的生命周期是较为经典也最清晰的,在此不表: Fragment从出现到广泛运用也有一段时间了,其标准生命周期也仅比Activity ...

  6. 向 ViewPager 中添加 包含 ListView 的 Fragment

    对与fragment就不说什么了,直接看API手册吧,亲. 向 ViewPager 中添加 包含 ListView 的 Fragment 的过程比较麻烦.他所表现的效果就是新闻客户端的滑动翻页效果. ...

  7. 【原创】【ViewPager+Fragment】ViewPager中切换界面Fragment被销毁的问题分析

    ViewPager中切换界面Fragment被销毁的问题分析   1.使用场景 ViewPager+Fragment实现界面切换,界面数量>=3   2.Fragment生命周期以及与Activ ...

  8. 转载【ViewPager+Fragment】ViewPager中切换界面Fragment被销毁的问题分析

    ViewPager中切换界面Fragment被销毁的问题分析  原文链接 http://www.cnblogs.com/monodin/p/3866441.html 1.使用场景 ViewPager+ ...

  9. ViewPager中Fragment的重复创建、复用问题

    在ViewPager中的Fragment的生命周期  随着页面的切换 当前的展示页相邻的页面生命周期一直在变化 一开始 刚进入Activity时候,ViewPager默认初始化好前两个Fragment ...

随机推荐

  1. Python性能分析指南(未完成)

    英文原文:http://www.huyng.com/posts/python-performance-analysis/ 译文:http://www.oschina.net/translate/pyt ...

  2. 前端 html head meta

    META(Metadata information) 提供有页面的元信息 例如:页面编码.刷新.跳转.针对搜索引擎和更新频道的描述和关键词 1.另外一种编码写法 <meta http-equiv ...

  3. centos 特殊权限 各种搜索命令 lsattr ,chattr,suid,sgid,sbit,file,type是否是内置命令,stat文件属性 ,whereis,locate,find,ln 内部命令和外部命令 第五节课

    centos 特殊权限 各种搜索命令 lsattr ,chattr,suid,sgid,sbit,file,type是否是内置命令,stat文件属性 ,whereis,locate,find,ln   ...

  4. React Native入门-刘望舒

    React Native入门(一)环境搭建与Hello World React Native入门(二)Atom+Nuclide安装.配置与调试 React Native入门(三)组件的Props(属性 ...

  5. 统计编程的框架与R语言统计分析基础——摘(1)

    清屏命令ctrl+L 一.基础 1.产生数据结构 a.直接输入 b.冒号,1:10 c.seq函数 d.rep函数 > 1:10 [1] 1 2 3 4 5 6 7 8 9 10 > 10 ...

  6. java多线程(五)

    Java 多线程同步 锁机制与synchronized 打个比方:一个object就像一个大房子,大门永远打开.房子里有很多房间(也就是方法).这些房间有上锁的(synchronized方法), 和不 ...

  7. enum 枚举类型默认值

    enum value { one, two, three, four }; 默认值

  8. Js中的filter()方法

    /* filter()方法使用指定的函数测试所有元素,并创建一个包含所有通过测试的元素的新数组. filter()基本语法: arr.filter(callback[, thisArg]) filte ...

  9. SpringData_CrudRepository接口

    CrudRepository CrudRepository 接口提供了最基本的对实体类的添删改查操作 T save(T entity);//保存单个实体 Iterable<T> save( ...

  10. 手把手教你学node.js之一个简单的express应用

    一个简单的express应用 目标 建立一个 lesson1 项目,在其中编写代码.当在浏览器中访问 http://localhost:3000/ 时,输出 Hello World. 挑战 访问 ht ...