现在越来越多的应用会使用viewpager+fragment显示自己的内容页,fragment和activity有很多共同点,如下图就是fragment的生命周期

但是fragment和activity不同的是当调用本身的onResume和onPause方法的时候可能并不是当前的fragment在显示,例如当加载下面这张图时,当我打开MainActivity时显示的是第一个fragment 但此时调用的方法步骤如下:

);

运行时打印的log和上面完全一致,即就算你设置只加载一个fragment还是会加载第二个fragment,原因是setOffscreenPageLimit中的源码时这样写的

[java] view plain copy
  1. public void setOffscreenPageLimit(int limit) {
  2. if (limit < DEFAULT_OFFSCREEN_PAGES) {
  3. Log.w(TAG, "Requested offscreen page limit " + limit + " too small; defaulting to " +
  4. DEFAULT_OFFSCREEN_PAGES);
  5. limit = DEFAULT_OFFSCREEN_PAGES;
  6. }
  7. if (limit != mOffscreenPageLimit) {
  8. mOffscreenPageLimit = limit;
  9. populate();
  10. }
  11. }

这个 DEFAULT_OFFSCREEN_PAGES 定义如下 private static final intDEFAULT_OFFSCREEN_PAGES= 1;

就是如果你设置为0 也没用。!!!

为了解决判断是否fragment当前显示问题 可以在fragment重写 setUserVisibleHint(boolean isVisibleToUser)

在fragment添加log日志

[java] view plain copy
  1. public class Fragment1 extends Fragment {
  2. private static final String TAG = "Fragment1";
  3. @Override
  4. public void onAttach(Activity activity) {
  5. super.onAttach(activity);
  6. L.v(TAG, "onAttach");
  7. }
  8. @Override
  9. public void setUserVisibleHint(boolean isVisibleToUser) {
  10. L.v(TAG, "setUserVisibleHint " + isVisibleToUser);
  11. }
  12. @Override
  13. public void onCreate(Bundle savedInstanceState) {
  14. super.onCreate(savedInstanceState);
  15. L.v(TAG, "onCreate");
  16. }
  17. @Override
  18. public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
  19. L.v(TAG, "onCreateView");
  20. View view = inflater.inflate(R.layout.fragment_layout,null);
  21. TextView tv = (TextView) view.findViewById(R.id.tv1);
  22. tv.setText(TAG);
  23. return view;
  24. }
  25. @Override
  26. public void onActivityCreated(@Nullable Bundle savedInstanceState) {
  27. super.onActivityCreated(savedInstanceState);
  28. L.v(TAG,"onActivityCreated");
  29. }
  30. @Override
  31. public void onResume() {
  32. super.onResume();
  33. L.v(TAG, "onResume()");
  34. }
  35. @Override
  36. public void onPause() {
  37. super.onPause();
  38. L.v(TAG,"onPause");
  39. }
  40. @Override
  41. public void onStop() {
  42. super.onStop();
  43. L.v(TAG,"onStop");
  44. }

启动activity打印日志如下:

08-11 11:33:36.156    7162-7162/com.example.yinsgo.myui V/Fragment1﹕ setUserVisibleHint false
08-11 11:33:36.156    7162-7162/com.example.yinsgo.myui V/Fragment2﹕ setUserVisibleHint false
08-11 11:33:36.157    7162-7162/com.example.yinsgo.myui V/Fragment1﹕ setUserVisibleHint true
08-11 11:33:36.158    7162-7162/com.example.yinsgo.myui V/Fragment1﹕ onAttach
08-11 11:33:36.158    7162-7162/com.example.yinsgo.myui V/Fragment1﹕ onCreate
08-11 11:33:36.159    7162-7162/com.example.yinsgo.myui V/Fragment1﹕ onCreateView
08-11 11:33:36.160    7162-7162/com.example.yinsgo.myui V/Fragment1﹕ onActivityCreated
08-11 11:33:36.160    7162-7162/com.example.yinsgo.myui V/Fragment1﹕ onResume()
08-11 11:33:36.160    7162-7162/com.example.yinsgo.myui V/Fragment2﹕ onAttach
08-11 11:33:36.160    7162-7162/com.example.yinsgo.myui V/Fragment2﹕ onCreate
08-11 11:33:36.160    7162-7162/com.example.yinsgo.myui V/Fragment2﹕ onCreateView
08-11 11:33:36.161    7162-7162/com.example.yinsgo.myui V/Fragment2﹕ onActivityCreated
08-11 11:33:36.161    7162-7162/com.example.yinsgo.myui V/Fragment2﹕ onResume()

当切换到第二个fragment时打印日志:

08-11 11:33:54.084    7162-7162/com.example.yinsgo.myui V/Fragment3﹕ setUserVisibleHint false
08-11 11:33:54.084    7162-7162/com.example.yinsgo.myui V/Fragment1﹕ setUserVisibleHint false
08-11 11:33:54.084    7162-7162/com.example.yinsgo.myui V/Fragment2﹕ setUserVisibleHint true
08-11 11:33:54.084    7162-7162/com.example.yinsgo.myui V/Fragment3﹕ onAttach
08-11 11:33:54.085    7162-7162/com.example.yinsgo.myui V/Fragment3﹕ onCreate
08-11 11:33:54.085    7162-7162/com.example.yinsgo.myui V/Fragment3﹕ onCreateView
08-11 11:33:54.085    7162-7162/com.example.yinsgo.myui V/Fragment3﹕ onActivityCreated
08-11 11:33:54.085    7162-7162/com.example.yinsgo.myui V/Fragment3﹕ onResume()

可见当fragment显示时回调用方法 setUserVisibleHint中的isVisibleToUser = true 当fragment被切换隐藏时回 isVisibleToUser = false;

所以当我们要统计是否用户看到一个fragment时可以执行一下代码

[java] view plain copy
  1. @Override
  2. public void setUserVisibleHint(boolean isVisibleToUser) {
  3. L.v(TAG, "setUserVisibleHint " + isVisibleToUser);
  4. if (isVisibleToUser) {
  5. //统计代码 或者 fragment显示操作
  6. } else {
  7. }
  8. }

同时根据这个方法还可以进行数据的延迟加载,后面再写。

今天又看了一下发现单纯的执行上面的代码是有问题的,因为如果我们在else中认为用户是离开界面其实是不对的,因为根据启动第一个Fragment的log日志

08-11 11:33:36.156    7162-7162/com.example.yinsgo.myui V/Fragment1﹕ setUserVisibleHint false
08-11 11:33:36.156    7162-7162/com.example.yinsgo.myui V/Fragment2﹕ setUserVisibleHint false
08-11 11:33:36.157    7162-7162/com.example.yinsgo.myui V/Fragment1﹕ setUserVisibleHint true
08-11 11:33:36.158    7162-7162/com.example.yinsgo.myui V/Fragment1﹕ onAttach
08-11 11:33:36.158    7162-7162/com.example.yinsgo.myui V/Fragment1﹕ onCreate
08-11 11:33:36.159    7162-7162/com.example.yinsgo.myui V/Fragment1﹕ onCreateView
08-11 11:33:36.160    7162-7162/com.example.yinsgo.myui V/Fragment1﹕ onActivityCreated
08-11 11:33:36.160    7162-7162/com.example.yinsgo.myui V/Fragment1﹕ onResume()
08-11 11:33:36.160    7162-7162/com.example.yinsgo.myui V/Fragment2﹕ onAttach
08-11 11:33:36.160    7162-7162/com.example.yinsgo.myui V/Fragment2﹕ onCreate
08-11 11:33:36.160    7162-7162/com.example.yinsgo.myui V/Fragment2﹕ onCreateView
08-11 11:33:36.161    7162-7162/com.example.yinsgo.myui V/Fragment2﹕ onActivityCreated
08-11 11:33:36.161    7162-7162/com.example.yinsgo.myui V/Fragment2﹕ onResume()

第一次setUserVisibleHint 方法 isVisibleToUser 是false 但其实这个时候只是还未初始化,并不是用户已经浏览界面准备离开,于是这里我们需要一个辅助标记变量具体代码如下:

[java] view plain copy
  1. /**
  2. * 判断是否是初始化Fragment
  3. */
  4. private boolean hasStarted = false;
  5. @Override
  6. public void setUserVisibleHint(boolean isVisibleToUser) {
  7. super.setUserVisibleHint(isVisibleToUser);
  8. L.v(TAG, "setUserVisibleHint " + isVisibleToUser);
  9. if (isVisibleToUser) {
  10. hasStarted = true;
  11. L.v(TAG,"开始界面");
  12. } else {
  13. if (hasStarted) {
  14. hasStarted = false;
  15. L.v(TAG,"结束界面");
  16. }
  17. }
  18. }

当我们启动MainActivity时 Log打印如下:

08-13 17:55:45.850  21467-21467/com.example.yinsgo.myui V/Fragment1﹕ setUserVisibleHint false
08-13 17:55:45.850  21467-21467/com.example.yinsgo.myui V/Fragment2﹕ setUserVisibleHint false
08-13 17:55:45.850  21467-21467/com.example.yinsgo.myui V/Fragment1﹕ onAttach
08-13 17:55:45.850  21467-21467/com.example.yinsgo.myui V/Fragment1﹕ onCreate
08-13 17:55:45.850  21467-21467/com.example.yinsgo.myui V/Fragment1﹕ setUserVisibleHint true
08-13 17:55:45.860  21467-21467/com.example.yinsgo.myui V/Fragment1﹕ 开始界面
08-13 17:55:45.860  21467-21467/com.example.yinsgo.myui V/Fragment1﹕ onCreateView
08-13 17:55:45.870  21467-21467/com.example.yinsgo.myui V/Fragment1﹕ onActivityCreated
08-13 17:55:45.880  21467-21467/com.example.yinsgo.myui V/Fragment1﹕ onResume()
08-13 17:55:45.880  21467-21467/com.example.yinsgo.myui V/Fragment2﹕ onAttach
08-13 17:55:45.880  21467-21467/com.example.yinsgo.myui V/Fragment2﹕ onCreate
08-13 17:55:45.880  21467-21467/com.example.yinsgo.myui V/Fragment2﹕ onCreateView
08-13 17:55:45.880  21467-21467/com.example.yinsgo.myui V/Fragment2﹕ onActivityCreated
08-13 17:55:45.880  21467-21467/com.example.yinsgo.myui V/Fragment2﹕ onResume()

切换到第二个fragment时,此时离开第一个fagment  log打印如下

08-13 17:57:04.310  21467-21467/com.example.yinsgo.myui V/Fragment3﹕ setUserVisibleHint false
08-13 17:57:04.310  21467-21467/com.example.yinsgo.myui V/Fragment1﹕ setUserVisibleHint false
08-13 17:57:04.310  21467-21467/com.example.yinsgo.myui V/Fragment1﹕ 结束界面
08-13 17:57:04.310  21467-21467/com.example.yinsgo.myui V/Fragment2﹕ setUserVisibleHint true
08-13 17:57:04.310  21467-21467/com.example.yinsgo.myui V/Fragment2﹕ 开始界面
08-13 17:57:04.310  21467-21467/com.example.yinsgo.myui V/Fragment3﹕ onAttach
08-13 17:57:04.310  21467-21467/com.example.yinsgo.myui V/Fragment3﹕ onCreate
08-13 17:57:04.310  21467-21467/com.example.yinsgo.myui V/Fragment3﹕ onCreateView
08-13 17:57:04.320  21467-21467/com.example.yinsgo.myui V/Fragment3﹕ onActivityCreated
08-13 17:57:04.320  21467-21467/com.example.yinsgo.myui V/Fragment3﹕ onResume()

切换到第三个fragment时,此时离开第二个fragment log打印如下:

08-13 17:58:15.040  21467-21467/com.example.yinsgo.myui V/Fragment2﹕ setUserVisibleHint false
08-13 17:58:15.040  21467-21467/com.example.yinsgo.myui V/Fragment2﹕ 结束界面
08-13 17:58:15.040  21467-21467/com.example.yinsgo.myui V/Fragment3﹕ setUserVisibleHint true
08-13 17:58:15.040  21467-21467/com.example.yinsgo.myui V/Fragment3﹕ 开始界面
08-13 17:58:15.040  21467-21467/com.example.yinsgo.myui V/Fragment1﹕ onPause
08-13 17:58:15.040  21467-21467/com.example.yinsgo.myui V/Fragment1﹕ onStop

可见这样就可以准确统计用户是否离开或者开始浏览界面了。根据这些开始和离开可以统计用户停留界面的时间等数据。

setUserVisibleHint-- fragment真正的onResume和onPause方法的更多相关文章

  1. Android setUserVisibleHint-- fragment真正的onResume和onPause方法

    这个情况仅适合与多个fragment之间切换时统计,而非activity和fragment同时交互,因当时项目为首页4个fargment时长统计,因此适合,经下面网友评论指出,特在这里写出此问题,因最 ...

  2. setUserVisibleHint-- fragment真正的onResume和onPause方法

    现在越来越多的应用会使用viewpager+fragment显示自己的内容页,fragment和activity有很多共同点,如下图就是fragment的生命周期 但是fragment和activit ...

  3. Fragment的可见再载入的方法(真正的Fragment的OnResume和OnPause)

    一 起因 我们在做应用的过程中,一个应用的界面可能是多个Fragment切换而成的.可是如果在每次应用启动的时候就去载入大量的网络数据(如果你的每一个Fragment都须要载入网络数据.你也能够理解为 ...

  4. 【Android】Fragment真正意义上的onResume和onPause

    前言 Fragment虽然有onResume和onPause的,但是这两个方法是Activity的方法,调用时机也是与Activity相同,和ViewPager搭配使用这个方法就很鸡肋了,根本不是你想 ...

  5. Android Fragment真正意义上的onResume和onPause

    Fragment虽然有onResume和onPause的,但是这两个方法是Activity的方法,调用时机也是与Activity相同,和ViewPager搭配使用这个方法就很鸡肋了,根本不是你想要的效 ...

  6. Activity 重载方法 onStart和onResume、onPause和onStop的区别

    Activity 重载方法 onStart和onResume.onPause和onStop的区别 首先了解Activity的四种状态 Running状态:一个新的Activity启动入栈后,它在屏幕最 ...

  7. Android Activity为什么要细化出onCreate、onStart、onResume、onPause、onStop、onDesdroy这么多方法让应用去重载?

    原文:http://www.xuebuyuan.com/1608083.html 最近在研究Activity的启动流程,老罗的blog在看,也找了其它资料学习,也跟过Android4.3的源码, 在跟 ...

  8. 【转】【Android UI设计与开发】第07期:底部菜单栏(二)Fragment的详细介绍和使用方法

    原始地址:http://blog.csdn.net/yangyu20121224/article/category/1431917/1 由于TabActivity在Android4.0以后已经被完全弃 ...

  9. Fragment 的生命周期及使用方法详解

    Fragment 的基础知识介绍 1.1 概述 1.1.1 特性 By hebang32624 Fragment 是 activity 的界面中的一部分或一种行为.可以把多个 Fragment 组合到 ...

随机推荐

  1. 解决Illegal mix of collations (latin1_swedish_ci,IMPLICIT) and (utf8_general_ci,COER

    今天在用java与mysql数据库时发现Illegal mix of collations (latin1_swedish_ci,IMPLICIT) and (utf8_general_ci,COER ...

  2. 为Qemu aarch32添加BeautifulSoup4模块

    环境 Qemu:2.8.0 开发板:vexpress-ca9   概述 上一篇博文已经可以让我们的开发板可以成功的ping通百度了,据说Python的网络功能也很强大,而Beautiful Soup是 ...

  3. 在Android.mk文件中输出打印消息

    http://www.xuebuyuan.com/1947880.html 在进行Android NDK的开发当中有时想看看Android.mk文件当中某个变量的值,可以再Android.mk文件当中 ...

  4. sharepoint 2013 网站集解锁

    前言 最近碰到这样的一个问题,就是SharePoint 站点备份(Backup-SPSite)的时候,速度特别慢,然后网站变成只读状态(备份过程中只读属于正常现象).但是,自己手欠把备份命令的Powe ...

  5. Swift - 多个mask的动画效果

    Swift - 多个mask的动画效果 效果 源码 https://github.com/YouXianMing/Swift-Animations // // TranformFadeView.swi ...

  6. 如何解决SSH连接Linux超时自动断开?

    最近项目开发中用到云服务器,部署了MySQL,开发团队总是反映MySQL过一会儿就断开连接了,必须手动重连才可以.反映越来越强烈,已经到了影响开发进度的高度了,必须解决! 查了资料,这个可能和SSH超 ...

  7. Android:客户端和服务器之间传输数据加密

    Android客户端与服务器进行数据传输时,一般会涉及到两类数据的加密情况,一类是只有创建者才能知道的数据,比如密码:另一类是其他比较重要的,但是可以逆向解密的数据. 第一类:密码类的数据,为了让用户 ...

  8. Netty精粹之JAVA NIO开发需要知道的

    学习Netty框架以及相关源码也有一小段时间了,恰逢今天除夕,写篇文章总结一下.Netty是个高效的JAVA NIO框架,总体框架基于异步非阻塞的设计,基于网络IO事件驱动,主要贡献在于可以让用户基于 ...

  9. ORM(Object-Relational Mapping 对象关系映射)如何实现(转)

    原文链接:http://blog.163.com/hzd_love/blog/static/13199988120107891854473/ 1.什么是ORM ORM的全称是Object Relati ...

  10. rsync推送备份服务器(Linux)

    rsync推送备份服务器备份服务器操作需被备份的服务器操作批处理shell备份服务器操作#编辑配置文件vi /etc/rsyncd.conf uid = root #运行RSYNC守护进程的用户gid ...