setUserVisibleHint-- fragment真正的onResume和onPause方法
现在越来越多的应用会使用viewpager+fragment显示自己的内容页,fragment和activity有很多共同点,如下图就是fragment的生命周期
但是fragment和activity不同的是当调用本身的onResume和onPause方法的时候可能并不是当前的fragment在显示,例如当加载下面这张图时,当我打开MainActivity时显示的是第一个fragment 但此时调用的方法步骤如下:

);
运行时打印的log和上面完全一致,即就算你设置只加载一个fragment还是会加载第二个fragment,原因是setOffscreenPageLimit中的源码时这样写的
- 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;
- }
- if (limit != mOffscreenPageLimit) {
- mOffscreenPageLimit = limit;
- populate();
- }
- }
这个 DEFAULT_OFFSCREEN_PAGES 定义如下 private static final intDEFAULT_OFFSCREEN_PAGES= 1;
就是如果你设置为0 也没用。!!!
为了解决判断是否fragment当前显示问题 可以在fragment重写 setUserVisibleHint(boolean isVisibleToUser)
在fragment添加log日志
- public class Fragment1 extends Fragment {
- private static final String TAG = "Fragment1";
- @Override
- public void onAttach(Activity activity) {
- super.onAttach(activity);
- L.v(TAG, "onAttach");
- }
- @Override
- public void setUserVisibleHint(boolean isVisibleToUser) {
- L.v(TAG, "setUserVisibleHint " + isVisibleToUser);
- }
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- L.v(TAG, "onCreate");
- }
- @Override
- public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
- L.v(TAG, "onCreateView");
- View view = inflater.inflate(R.layout.fragment_layout,null);
- TextView tv = (TextView) view.findViewById(R.id.tv1);
- tv.setText(TAG);
- return view;
- }
- @Override
- public void onActivityCreated(@Nullable Bundle savedInstanceState) {
- super.onActivityCreated(savedInstanceState);
- L.v(TAG,"onActivityCreated");
- }
- @Override
- public void onResume() {
- super.onResume();
- L.v(TAG, "onResume()");
- }
- @Override
- public void onPause() {
- super.onPause();
- L.v(TAG,"onPause");
- }
- @Override
- public void onStop() {
- super.onStop();
- L.v(TAG,"onStop");
- }
启动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时可以执行一下代码
- @Override
- public void setUserVisibleHint(boolean isVisibleToUser) {
- L.v(TAG, "setUserVisibleHint " + isVisibleToUser);
- if (isVisibleToUser) {
- //统计代码 或者 fragment显示操作
- } else {
- }
- }
同时根据这个方法还可以进行数据的延迟加载,后面再写。
今天又看了一下发现单纯的执行上面的代码是有问题的,因为如果我们在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 但其实这个时候只是还未初始化,并不是用户已经浏览界面准备离开,于是这里我们需要一个辅助标记变量具体代码如下:
- /**
- * 判断是否是初始化Fragment
- */
- private boolean hasStarted = false;
- @Override
- public void setUserVisibleHint(boolean isVisibleToUser) {
- super.setUserVisibleHint(isVisibleToUser);
- L.v(TAG, "setUserVisibleHint " + isVisibleToUser);
- if (isVisibleToUser) {
- hasStarted = true;
- L.v(TAG,"开始界面");
- } else {
- if (hasStarted) {
- hasStarted = false;
- L.v(TAG,"结束界面");
- }
- }
- }
当我们启动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方法的更多相关文章
- Android setUserVisibleHint-- fragment真正的onResume和onPause方法
这个情况仅适合与多个fragment之间切换时统计,而非activity和fragment同时交互,因当时项目为首页4个fargment时长统计,因此适合,经下面网友评论指出,特在这里写出此问题,因最 ...
- setUserVisibleHint-- fragment真正的onResume和onPause方法
现在越来越多的应用会使用viewpager+fragment显示自己的内容页,fragment和activity有很多共同点,如下图就是fragment的生命周期 但是fragment和activit ...
- Fragment的可见再载入的方法(真正的Fragment的OnResume和OnPause)
一 起因 我们在做应用的过程中,一个应用的界面可能是多个Fragment切换而成的.可是如果在每次应用启动的时候就去载入大量的网络数据(如果你的每一个Fragment都须要载入网络数据.你也能够理解为 ...
- 【Android】Fragment真正意义上的onResume和onPause
前言 Fragment虽然有onResume和onPause的,但是这两个方法是Activity的方法,调用时机也是与Activity相同,和ViewPager搭配使用这个方法就很鸡肋了,根本不是你想 ...
- Android Fragment真正意义上的onResume和onPause
Fragment虽然有onResume和onPause的,但是这两个方法是Activity的方法,调用时机也是与Activity相同,和ViewPager搭配使用这个方法就很鸡肋了,根本不是你想要的效 ...
- Activity 重载方法 onStart和onResume、onPause和onStop的区别
Activity 重载方法 onStart和onResume.onPause和onStop的区别 首先了解Activity的四种状态 Running状态:一个新的Activity启动入栈后,它在屏幕最 ...
- Android Activity为什么要细化出onCreate、onStart、onResume、onPause、onStop、onDesdroy这么多方法让应用去重载?
原文:http://www.xuebuyuan.com/1608083.html 最近在研究Activity的启动流程,老罗的blog在看,也找了其它资料学习,也跟过Android4.3的源码, 在跟 ...
- 【转】【Android UI设计与开发】第07期:底部菜单栏(二)Fragment的详细介绍和使用方法
原始地址:http://blog.csdn.net/yangyu20121224/article/category/1431917/1 由于TabActivity在Android4.0以后已经被完全弃 ...
- Fragment 的生命周期及使用方法详解
Fragment 的基础知识介绍 1.1 概述 1.1.1 特性 By hebang32624 Fragment 是 activity 的界面中的一部分或一种行为.可以把多个 Fragment 组合到 ...
随机推荐
- jQuery把所有被选中的checkbox的某个属性值连接成字符串
有这样的一个需求:对于一组checkbox,当点击每个checkbox后,把当前处于选中状态的checkbox的某个属性值取出来连接成字符串,并以逗号分开. html部分: <input typ ...
- 在ASP.NET MVC下有关上传图片脏数据的解决方案
在"在ASP.NET MVC下实现单个图片上传, 客户端服务端双重限制图片大小和格式, 服务端裁剪图片"中,已经实现了在客户端和服务端限制图片大小和格式,以及在服务端裁剪图片.但还 ...
- Android 模拟器设置
这几个图标你应该是没有见过的,我来简单为你介绍下.最左边的图标其实你已经比较熟悉了,就是你睡觉前使用过的Android SDK管理器,点击它和点击SDK Manager效果是一样的.中间的图标是用来开 ...
- uistatusBar 详解
成功的方法: 方法1.隐藏应用程序内所有的StatusBar 第一步:在Info.plist,然后添加一个新的row,"View controller-based status bar ap ...
- Python:Hello World级别的SimpleDb
背景 几乎所有的动态语言都支持成员的动态解析,一般的在解析不到成员的时候会给出一个hook点让你自定义一些有意思的实现..Net4之后增加了对动态类型的支持,在动态类型上就有这种机制. 模拟Simpl ...
- POJ1580 水题,积累!
[题意简述]:题意非常easy.就是将这两个字符串比較,移动着比較.求出最多的同样的元素个数.然后用题目中所给的公式,写出结果. [分析]:本题要注意的就是for循环的形式.注意积累就可以. 详见代码 ...
- wince程序调用另外一个wince exe程序?
记住:要释放句柄 清空内存(当前程序) 在虚拟机下测试如图: 在reyo.ini文件中配置另一wince执行程序的路径,如果不配置程序会报错: 如果配置的程序不存在报错: 没有问题就调用所在位置的wi ...
- IOS的唯一标识符问题(转)
引用地址 http://www.zhihu.com/question/22599526/answer/21938878 网上搜了下IOS手机标志的种类,直接引用过来. UDID [[UIDevice ...
- 手游开发Android平台周边工具介绍
1.渠道接入 主要是需要接入各平台的登录.充值接口,各家SDK又不统一,Android渠道都是鱼龙混杂,就算小渠道你看不上,但量多了,加起来也还可观,所以大家都拿出吃奶的尽去铺渠道.国内几大主要的An ...
- 自定义的圆形ProgressBar
之前已经详细讲解过自定义控件的使用方式了.这里我单独把定以好的控件列出来. 之前定义的各式各样的ProgressBar http://www.cnblogs.com/tianzhijiexia ...