ViewPager Fragment动态添加以及动态删除的理解

       近期在做一个类似于问卷调查答题的一个项目,涉及到Viewpager+Frament的使用,需要使用ViewPager中的Fragement去显示每一道题目,并且可以实现点击上一题和下一题的操作,与一般使用不一样的地方是,每套问卷的题目数量不一样,下一题的跳转是根据当前题的选项去决定,所以Frament的界面数量不能确定,无法事先存放。后来我就采用了进行动态添加Fragment和动态删除Fragment的方式去处理这样的需求,当然之后就遇到很多问题了。。

      

       一开始我想法很简单就是把viewpager当成一般的adapter来做,添加和删除,直接用list的add和remove来操作,之后在adapter.notifyDataSetChanged去更新adapter,结果发现删除没啥问题,但是删除后在添加后,奇怪的是再添加的界面上的数据与之前删除的界面上的数据一样。。而且我调用界面上的控件就会出空指针异常。我第一直觉告诉我是,我没有删除那个界面添加只是调用了原先的那个界面,我就想会不会是viewpager的缓存问题。

      

       之后就开始找网上的资料,搜索关于viewpager的缓存的问题。然后我找到关于viewPager.setOffscreenPageLimit(num);// 设置缓存页面,当前页面的相邻N各页面都会被缓存 ,这个方法setOffscreenPageLimit(num),几经测试过后发现并没有我想要那个效果,就算我设置为0删除添加后也还是会有界面缓存的,结果发现这个方法是用作与预加载时用的,当前如果有5个界面,我设置setOffscreenPageLimit为2当我显示第一个界面的时候,其实我已经在加载了第二第三个界面,但我问题不是预加载出现的问题,就算我不预加载,将值设置为0,那结果就是每切换一个界面就执行当前自己的生命周期,但是其实我那个被删除的界面一直缓存着,这种方式只是重新走了下他的生命周期而已,并没有创建新的Fragment

      

      然后我开始从notifyDataSetChanged这里去找问题,感谢下这位同学分享的http://blog.csdn.net/u013034750/article/details/24323123 也是这篇文章让知道了原来是FragmentManager缓存了界面,必须在instantiateItem()中用FragmentTransaction去remove这个Fragment。


     最后通过这篇文章http://blog.csdn.net/z13759561330/article/details/40737381 完美的解决了我的问题,每次在调用instantiateItem的时候我去判断是否最后一个标签页,是否是再次添加的界面,是否已经删除过的界面,达成这些判断的时候我将最后那个界面的Fragment进行替换成list中最后一项的界面。我就直接上代码看啦。。


private class MyPagerFragmentAdapter extends FragmentPagerAdapter {
		private List<Fragment> fragments;
		private FragmentManager fm;

		public MyPagerFragmentAdapter(FragmentManager fm,
				List<Fragment> fragments) {
			super(fm);
			this.fm = fm;
			this.fragments = fragments;
		}

		@Override
		public void destroyItem(ViewGroup container, int position, Object object) {
			Log.i("TAG", "destroyItem___________");
			super.destroyItem(container, position, object);
		}

		@Override
		public Object instantiateItem(ViewGroup container, int position) {
			Log.i("TAG", "instantiateItem___________");
			// 得到缓存的fragment
			Fragment fragment = (Fragment) super.instantiateItem(container,
					position);
			// 得到tag,这点很重要
			String fragmentTag = fragment.getTag();
			Log.i("TAG", "替换___________1");
			if (position == (fragmentList.size() - 1)) {// 是否为最后一页(因为会根据setOffscreenPageLimit的数量执行相应次数)
				if (isDelete) {// 是否被删除过,删除事件中修改为True
					if (isAdd) {// 是否点击了添加,添加事件中修改为True
						Log.i("TAG", "替换___________2");
						// 如果这个fragment需要更新

						FragmentTransaction ft = fm.beginTransaction();
						// 移除旧的fragment
						ft.remove(fragment);
						// 换成新的fragment
						fragment = fragments.get(fragmentList.size() - 1);
						// 添加新fragment时必须用前面获得的tag,这点很重要
						ft.add(container.getId(), fragment, fragmentTag);
						ft.attach(fragment);
						ft.commit();
						isAdd = false;
						isDelete = false;
					}
				}
			}
			return fragment;
		}

		@Override
		public int getItemPosition(Object object) {
			Log.i("TAG", "getItemPosition___________");
			return POSITION_NONE;
		}

		@Override
		public Fragment getItem(int arg0) {
			Log.i("TAG", "getitem___________");
			return fragments.get(arg0);
		}

		@Override
		public int getCount() {
			Log.i("TAG", "getCount___________");
			return fragments.size();
		}

	}

      总结:以上是我对Viewpager+Fragment的使用以及遇到的问题的总结,可能不完善,或不专业,望看到此贴的大牛指点,谢谢!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值