学习fragment 中的坑

参考:
http://www.360doc.com/content/12/0517/15/5087210_211679689.shtml

1、fragment 和activity
Fragment如何产生,什么是Fragment,Fragment生命周期,如何静态和动态使用Fragment,Fragment回退栈,Fragment事务,以及Fragment结合viewpager使用,框架android-viewpagerindicator等。

http://blog.csdn.net/hjj0212/article/details/8530273
onattach
oncreate
oncreateview
onactivitycreated

onstart
onresume

onpause
onstop
ondestroyview
ondestroy
ondetach

一般情况在activityoncreate时候进行fragment的创建,所以
在创建和运行过程
fragment是跟着activity后面执行生命周期的;
在pause—destroy过程
fragment先感知到,
所以 fragment先执行方法,之后activity跟在后面执行。

当然这个过程可能随着添加fragment位置不同,有所变化,
但是大体是不会变的。

2、fragment+viewpager联合使用
viewpager—listview
fragment—相当于每一条显示的item
这里写图片描述

当前的viewpager中加载了5个fragment,
默认viewpager是缓存相邻1个fragment
源码:

 public void setOffscreenPageLimit(int limit) {
        if (limit < DEFAULT_OFFSCREEN_PAGES) {
            Log.w(TAG, "Requested offscreen page limit " + limit + " too small; defaulting to "
                    + DEFAULT_OFFSCREEN_PAGES);
            limit = DEFAULT_OFFSCREEN_PAGES;//1
        }
        if (limit != mOffscreenPageLimit) {
            mOffscreenPageLimit = limit;
            populate();
        }
    }

当我位于最左边‘’头条‘’,只有右边有一个,所以应该是缓存创建‘’社会‘’

06-01 14:31:57.384 21319-21319/com.example.lihui20.testhttp D/BaseFragment531: typeFragment---,BaseFragment onAttach
06-01 14:31:57.390 21319-21319/com.example.lihui20.testhttp D/BaseFragment531: typeFragment---top,BaseFragment onCreate
06-01 14:31:57.390 21319-21319/com.example.lihui20.testhttp D/BaseFragment531: typeFragment---top,创建的BaseFragment type---top
06-01 14:31:57.391 21319-21319/com.example.lihui20.testhttp D/BaseFragment531: typeFragment---,BaseFragment onAttach
06-01 14:31:57.391 21319-21319/com.example.lihui20.testhttp D/BaseFragment531: typeFragment---shehui,BaseFragment onCreate
06-01 14:31:57.391 21319-21319/com.example.lihui20.testhttp D/BaseFragment531: typeFragment---shehui,创建的BaseFragment type---shehui
06-01 14:31:57.394 21319-21319/com.example.lihui20.testhttp D/BaseFragment531: typeFragment---top,BaseFragment onCreateView
06-01 14:31:57.528 21319-21319/com.example.lihui20.testhttp D/BaseFragment531: typeFragment---top,BaseFragment onActivityCreated
06-01 14:31:57.528 21319-21319/com.example.lihui20.testhttp D/BaseFragment531: typeFragment---top,BaseFragment onResume
06-01 14:31:57.614 21319-21319/com.example.lihui20.testhttp D/BaseFragment531: typeFragment---shehui,BaseFragment onCreateView
06-01 14:31:57.649 21319-21319/com.example.lihui20.testhttp D/BaseFragment531: typeFragment---shehui,BaseFragment onActivityCreated
06-01 14:31:57.649 21319-21319/com.example.lihui20.testhttp D/BaseFragment531: typeFragment---shehui,BaseFragment onResume

当我位于‘’国内‘’,应该会创建‘’社会‘’,‘’国际‘’
,并且销毁‘’头条‘’,由于‘’社会‘’已经缓存了,所以不会再次创建。

06-01 14:33:29.745 21319-21319/com.example.lihui20.testhttp D/BaseFragment531: typeFragment---,BaseFragment onAttach
06-01 14:33:29.745 21319-21319/com.example.lihui20.testhttp D/BaseFragment531: typeFragment---guonei,BaseFragment onCreate
06-01 14:33:29.745 21319-21319/com.example.lihui20.testhttp D/BaseFragment531: typeFragment---guonei,创建的BaseFragment type---guonei
06-01 14:33:29.745 21319-21319/com.example.lihui20.testhttp D/BaseFragment531: typeFragment---,BaseFragment onAttach
06-01 14:33:29.745 21319-21319/com.example.lihui20.testhttp D/BaseFragment531: typeFragment---guoji,BaseFragment onCreate
06-01 14:33:29.745 21319-21319/com.example.lihui20.testhttp D/BaseFragment531: typeFragment---guoji,创建的BaseFragment type---guoji
06-01 14:33:29.746 21319-21319/com.example.lihui20.testhttp D/BaseFragment531: typeFragment---guonei,BaseFragment onCreateView
06-01 14:33:29.779 21319-21319/com.example.lihui20.testhttp D/BaseFragment531: typeFragment---guonei,BaseFragment onActivityCreated
06-01 14:33:29.780 21319-21319/com.example.lihui20.testhttp D/BaseFragment531: typeFragment---guonei,BaseFragment onResume
06-01 14:33:29.790 21319-21319/com.example.lihui20.testhttp D/BaseFragment531: typeFragment---guoji,BaseFragment onCreateView
06-01 14:33:29.812 21319-21319/com.example.lihui20.testhttp D/BaseFragment531: typeFragment---guoji,BaseFragment onActivityCreated
06-01 14:33:29.812 21319-21319/com.example.lihui20.testhttp D/BaseFragment531: typeFragment---guoji,BaseFragment onResume
06-01 14:33:29.825 21319-21319/com.example.lihui20.testhttp D/BaseFragment531: typeFragment---top,BaseFragment onPause
06-01 14:33:29.825 21319-21319/com.example.lihui20.testhttp D/BaseFragment531: typeFragment---top,BaseFragment onStop
06-01 14:33:29.825 21319-21319/com.example.lihui20.testhttp D/BaseFragment531: typeFragment---top,BaseFragment onDestroyView
06-01 14:33:29.832 21319-21319/com.example.lihui20.testhttp D/BaseFragment531: typeFragment---top,BaseFragment onDestroy
06-01 14:33:29.832 21319-21319/com.example.lihui20.testhttp D/BaseFragment531: typeFragment---top,BaseFragment onDetach

这时候再次点击头条,应该会重新加载‘’头条‘’,销毁‘’国内‘’和‘’国际‘’,‘’社会‘’不会变。

06-01 14:37:43.731 21319-21319/com.example.lihui20.testhttp D/BaseFragment531: typeFragment---,BaseFragment onAttach
06-01 14:37:43.731 21319-21319/com.example.lihui20.testhttp D/BaseFragment531: typeFragment---top,BaseFragment onCreate
06-01 14:37:43.731 21319-21319/com.example.lihui20.testhttp D/BaseFragment531: typeFragment---top,创建的BaseFragment type---top
06-01 14:37:43.732 21319-21319/com.example.lihui20.testhttp D/BaseFragment531: typeFragment---top,BaseFragment onCreateView
06-01 14:37:43.758 21319-21319/com.example.lihui20.testhttp D/BaseFragment531: typeFragment---top,BaseFragment onActivityCreated
06-01 14:37:43.759 21319-21319/com.example.lihui20.testhttp D/BaseFragment531: typeFragment---top,BaseFragment onResume
06-01 14:37:43.775 21319-21319/com.example.lihui20.testhttp D/BaseFragment531: typeFragment---guonei,BaseFragment onPause
06-01 14:37:43.775 21319-21319/com.example.lihui20.testhttp D/BaseFragment531: typeFragment---guonei,BaseFragment onStop
06-01 14:37:43.775 21319-21319/com.example.lihui20.testhttp D/BaseFragment531: typeFragment---guonei,BaseFragment onDestroyView
06-01 14:37:43.781 21319-21319/com.example.lihui20.testhttp D/BaseFragment531: typeFragment---guonei,BaseFragment onDestroy
06-01 14:37:43.781 21319-21319/com.example.lihui20.testhttp D/BaseFragment531: typeFragment---guonei,BaseFragment onDetach
06-01 14:37:43.781 21319-21319/com.example.lihui20.testhttp D/BaseFragment531: typeFragment---guoji,BaseFragment onPause
06-01 14:37:43.782 21319-21319/com.example.lihui20.testhttp D/BaseFragment531: typeFragment---guoji,BaseFragment onStop
06-01 14:37:43.782 21319-21319/com.example.lihui20.testhttp D/BaseFragment531: typeFragment---guoji,BaseFragment onDestroyView
06-01 14:37:43.784 21319-21319/com.example.lihui20.testhttp D/BaseFragment531: typeFragment---guoji,BaseFragment onDestroy
06-01 14:37:43.784 21319-21319/com.example.lihui20.testhttp D/BaseFragment531: typeFragment---guoji,BaseFragment onDetach

好了,既然说加载当前相邻的2个fragment,那么我们再点击‘’国际‘’,应该加载‘’国内‘’,‘’娱乐‘’,删除‘’头条‘’
‘’社会‘’

06-01 15:04:59.649 21319-21319/com.example.lihui20.testhttp D/BaseFragment531: typeFragment---,BaseFragment onAttach
06-01 15:04:59.649 21319-21319/com.example.lihui20.testhttp D/BaseFragment531: typeFragment---guoji,BaseFragment onCreate
06-01 15:04:59.649 21319-21319/com.example.lihui20.testhttp D/BaseFragment531: typeFragment---guoji,创建的BaseFragment type---guoji
06-01 15:04:59.649 21319-21319/com.example.lihui20.testhttp D/BaseFragment531: typeFragment---,BaseFragment onAttach
06-01 15:04:59.649 21319-21319/com.example.lihui20.testhttp D/BaseFragment531: typeFragment---guonei,BaseFragment onCreate
06-01 15:04:59.649 21319-21319/com.example.lihui20.testhttp D/BaseFragment531: typeFragment---guonei,创建的BaseFragment type---guonei
06-01 15:04:59.649 21319-21319/com.example.lihui20.testhttp D/BaseFragment531: typeFragment---,BaseFragment onAttach
06-01 15:04:59.649 21319-21319/com.example.lihui20.testhttp D/BaseFragment531: typeFragment---yule,BaseFragment onCreate
06-01 15:04:59.649 21319-21319/com.example.lihui20.testhttp D/BaseFragment531: typeFragment---yule,创建的BaseFragment type---yule
06-01 15:04:59.653 21319-21319/com.example.lihui20.testhttp D/BaseFragment531: typeFragment---guonei,BaseFragment onCreateView
06-01 15:04:59.673 21319-21319/com.example.lihui20.testhttp D/BaseFragment531: typeFragment---guonei,BaseFragment onActivityCreated
06-01 15:04:59.673 21319-21319/com.example.lihui20.testhttp D/BaseFragment531: typeFragment---guoji,BaseFragment onCreateView
06-01 15:04:59.692 21319-21319/com.example.lihui20.testhttp D/BaseFragment531: typeFragment---guoji,BaseFragment onActivityCreated
06-01 15:04:59.693 21319-21319/com.example.lihui20.testhttp D/BaseFragment531: typeFragment---yule,BaseFragment onCreateView
06-01 15:04:59.707 21319-21319/com.example.lihui20.testhttp D/BaseFragment531: typeFragment---yule,BaseFragment onActivityCreated
06-01 15:04:59.707 21319-21319/com.example.lihui20.testhttp D/BaseFragment531: typeFragment---guonei,BaseFragment onResume
06-01 15:04:59.713 21319-21319/com.example.lihui20.testhttp D/BaseFragment531: typeFragment---guoji,BaseFragment onResume
06-01 15:04:59.721 21319-21319/com.example.lihui20.testhttp D/BaseFragment531: typeFragment---yule,BaseFragment onResume
06-01 15:04:59.732 21319-21319/com.example.lihui20.testhttp D/BaseFragment531: typeFragment---shehui,BaseFragment onPause
06-01 15:04:59.732 21319-21319/com.example.lihui20.testhttp D/BaseFragment531: typeFragment---shehui,BaseFragment onStop
06-01 15:04:59.733 21319-21319/com.example.lihui20.testhttp D/BaseFragment531: typeFragment---shehui,BaseFragment onDestroyView
06-01 15:04:59.735 21319-21319/com.example.lihui20.testhttp D/BaseFragment531: typeFragment---shehui,BaseFragment onDestroy
06-01 15:04:59.735 21319-21319/com.example.lihui20.testhttp D/BaseFragment531: typeFragment---shehui,BaseFragment onDetach
06-01 15:04:59.735 21319-21319/com.example.lihui20.testhttp D/BaseFragment531: typeFragment---top,BaseFragment onPause
06-01 15:04:59.735 21319-21319/com.example.lihui20.testhttp D/BaseFragment531: typeFragment---top,BaseFragment onStop
06-01 15:04:59.735 21319-21319/com.example.lihui20.testhttp D/BaseFragment531: typeFragment---top,BaseFragment onDestroyView
06-01 15:04:59.737 21319-21319/com.example.lihui20.testhttp D/BaseFragment531: typeFragment---top,BaseFragment onDestroy
06-01 15:04:59.737 21319-21319/com.example.lihui20.testhttp D/BaseFragment531: typeFragment---top,BaseFragment onDetach

可以看出缓存1,为了左右滑动流畅,已经创建了左右的fragment。
左右2边是,创建2个fragment;
中间是创建3个fragment。
创建之后,你2个页面左右滑动不会销毁,这就通过设置缓存页来避免fragment不断销毁再次创建。

如果你有10个fragment,想让所有页面加载后不销毁,设置缓存
9个。也就是说当你位于头、尾2端,左右各有9个页面,缓存9个,加自己当前显示1个,10个页面全部创建了。处于中间,左右肯定小于9个,
2 1 6
4 1 4
。。。
没有关系,有多少创建多少。
mPager.setOffscreenPageLimit(100);也没有关系,只有大于9都可以(这里10-1)

既然viewpager类似listview,那么肯定需要适配器吧。
viewpager有2种标准适配器:

  public class CustomAdapter extends FragmentStatePagerAdapter {}这个适合动态更新、添加
  、删除,多个fragment情况

  public class CustomAdapter extends FragmentPagerAdapter {}
  适合页面固定的fragment,4-5

adapter中重写方法:
使用FragmentPagerAdapter POSITION_UNCHANGED

06-01 15:57:39.401 19985-19985/com.example.lihui20.testhttp D/lihui1555: 364 fragmentTitlesList---[国际, 国内, 体育]
06-01 15:57:39.401 19985-19985/com.example.lihui20.testhttp D/lihui1555: getCount---3
06-01 15:57:39.401 19985-19985/com.example.lihui20.testhttp D/lihui1555: getCount---3
06-01 15:57:39.401 19985-19985/com.example.lihui20.testhttp D/lihui1555: 123 getPageTitle position---0
06-01 15:57:39.410 19985-19985/com.example.lihui20.testhttp D/lihui1555: 123 getPageTitle position---1
06-01 15:57:39.412 19985-19985/com.example.lihui20.testhttp D/lihui1555: 123 getPageTitle position---2
06-01 15:57:39.413 19985-19985/com.example.lihui20.testhttp D/lihui1555: getCount---3
06-01 15:57:39.414 19985-19985/com.example.lihui20.testhttp D/lihui1555: getCount---3
06-01 15:57:40.391 19985-19985/com.example.lihui20.testhttp D/lihui1555: getCount---3
06-01 15:57:40.391 19985-19985/com.example.lihui20.testhttp D/lihui1555: getCount---3
06-01 15:57:40.392 19985-19985/com.example.lihui20.testhttp D/lihui1555: getCount---3
06-01 15:57:40.392 19985-19985/com.example.lihui20.testhttp D/lihui1555: instantiateItem object---0
06-01 15:57:40.399 19985-19985/com.example.lihui20.testhttp D/lihui1555: 123 Fragment getItem---0
06-01 15:57:40.411 19985-19985/com.example.lihui20.testhttp D/lihui1555: instantiateItem object---1
06-01 15:57:40.411 19985-19985/com.example.lihui20.testhttp D/lihui1555: 123 Fragment getItem---1
06-01 15:57:40.412 19985-19985/com.example.lihui20.testhttp D/lihui1555: instantiateItem object---2
06-01 15:57:40.413 19985-19985/com.example.lihui20.testhttp D/lihui1555: 123 Fragment getItem---2

移除:

06-01 16:06:19.555 19985-19985/com.example.lihui20.testhttp D/lihui1555: getCount---1
06-01 16:06:19.556 19985-19985/com.example.lihui20.testhttp D/lihui1555: getItemPosition object---BaseFragment2{99d207 #0 id=0x7f0f00e0 android:switcher:2131689696:0}
06-01 16:06:19.557 19985-19985/com.example.lihui20.testhttp D/lihui1555: getItemPosition object---BaseFragment2{7e6bf34 #1 id=0x7f0f00e0 android:switcher:2131689696:1}
06-01 16:06:19.557 19985-19985/com.example.lihui20.testhttp D/lihui1555: getItemPosition object---BaseFragment2{1b9715d #2 id=0x7f0f00e0 android:switcher:2131689696:2}
06-01 16:06:19.579 19985-19985/com.example.lihui20.testhttp D/lihui1555: getCount---1
06-01 16:06:19.580 19985-19985/com.example.lihui20.testhttp D/lihui1555: 123 getPageTitle position---0

fragmentstatepageadapter+ POSITION_NONE

06-01 16:26:24.107 28297-28297/com.example.lihui20.testhttp D/lihui1555: getCount---3
06-01 16:26:24.216 28297-28297/com.example.lihui20.testhttp D/lihui1555: getCount---2
06-01 16:26:24.217 28297-28297/com.example.lihui20.testhttp D/lihui1555: getItemPosition object---BaseFragment2{66ec95b #0 id=0x7f0f00e0}
06-01 16:26:24.240 28297-28297/com.example.lihui20.testhttp D/lihui1555: destroyItem position---0
06-01 16:26:24.241 28297-28297/com.example.lihui20.testhttp D/lihui1555: destroyItem object---BaseFragment2{66ec95b #0 id=0x7f0f00e0}
06-01 16:26:24.242 28297-28297/com.example.lihui20.testhttp D/lihui1555: getItemPosition object---BaseFragment2{a65936 #1 id=0x7f0f00e0}
06-01 16:26:24.253 28297-28297/com.example.lihui20.testhttp D/lihui1555: destroyItem position---1
06-01 16:26:24.254 28297-28297/com.example.lihui20.testhttp D/lihui1555: destroyItem object---BaseFragment2{a65936 #1 id=0x7f0f00e0}
06-01 16:26:24.254 28297-28297/com.example.lihui20.testhttp D/lihui1555: getItemPosition object---BaseFragment2{bc6a037 #2 id=0x7f0f00e0}
06-01 16:26:24.266 28297-28297/com.example.lihui20.testhttp D/lihui1555: destroyItem position---2
06-01 16:26:24.267 28297-28297/com.example.lihui20.testhttp D/lihui1555: destroyItem object---BaseFragment2{bc6a037 #2 id=0x7f0f00e0}
06-01 16:26:24.284 28297-28297/com.example.lihui20.testhttp D/lihui1555: getCount---2
06-01 16:26:24.284 28297-28297/com.example.lihui20.testhttp D/lihui1555: getCount---2
06-01 16:26:24.284 28297-28297/com.example.lihui20.testhttp D/lihui1555: getCount---2
06-01 16:26:24.284 28297-28297/com.example.lihui20.testhttp D/lihui1555: instantiateItem object---0
06-01 16:26:24.284 28297-28297/com.example.lihui20.testhttp D/lihui1555: 123 Fragment getItem---0
06-01 16:26:24.285 28297-28297/com.example.lihui20.testhttp D/lihui1555: instantiateItem object---1
06-01 16:26:24.285 28297-28297/com.example.lihui20.testhttp D/lihui1555: 123 Fragment getItem---1
06-01 16:26:24.285 28297-28297/com.example.lihui20.testhttp D/lihui1555: getCount---2
06-01 16:26:24.353 28297-28297/com.example.lihui20.testhttp D/lihui1555: getCount---2
06-01 16:26:24.353 28297-28297/com.example.lihui20.testhttp D/lihui1555: 123 getPageTitle position---0
06-01 16:26:24.354 28297-28297/com.example.lihui20.testhttp D/lihui1555: 123 getPageTitle position---1
    @Override
        public int getItemPosition(Object object) {
            Log.d("lihui1555", "getItemPosition object---" + object);
            BaseFragment2 object2=(BaseFragment2)object;
             return POSITION_NONE;
        }

使用了这个POSITION_NONE,动态添加、删除fragment,会导致已经存在的fragment销毁然后重建。
这样导致原来界面需要重新请求网络数据,每次添加或者删除都要再次请求(前提我已经设置viewpager把所有界面都缓存了)。。。
我想改成添加、删除某个fragment,原来的fragment没有变化,即不执行任何生命周期方法,所有fragment界面数据还保存的,但是貌似无法实现啊。。。

尝试:
我使用了

return POSITION_UNCHANGED;

这个添加、删除fragment,其他界面不会销毁再重建,但是删除之后,发现刚刚删除 的fragment还是存在的,用力滑动可以出现,蛋疼啊。。。

我的解决方法是:
使用POSITION_NONE+fragmentstatepagerviewadapter,每次添加、删除某个fragment,如果你在fragment中需要访问网络了,把上一次请求的数据缓存到本地,没有网络时候离线加载缓存数据。
只能这么办了。。。

3、fragment+viewpager+导航栏(框架 android-viewpagerindicator)

https://github.com/JakeWharton/ViewPagerIndicator
原生的demo也存在动态删除fragment问题,
它使用的是
FragmentPagerAdapter+
return POSITION_UNCHANGED;
导致删除fragment,虽然当前界面看不到了,但是fragment依旧在内存中,你用力还可以滑动出来!!!

如果viewpager动态删除、添加fragment:
你是的是FragmentPagerAdapter +POSITION_NONE(当然使用POSITION_NONE,动态添加、删除时候已存在的fragment会销毁创建)
是可以实现的,但是我发现如果你的界面有tab对应pagetitle,会出现
title删除了,但是下面对应fragment会出现错乱,不对应,搞不清楚为什么!!!!!!晕死

fragment+事务
后面再说。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值