如何判断Fragment是否对用户可见

背景

最近在开发中遇到了一个问题。我们的app需要统计用户的页面路径,也就是用户使用各个页面的情况。这就需要在不同的页面跳入和跳出时记录下来。但是我们的app主要是由Fragment构成的。而在不同的使用情况下,判断Fragment是否可见的方法是不一样的。下面对这些不同的使用情况分开分析。

不同的情况

在Activity中直接使用

这种情况是最简单的,也就是在Activity使用XML引入,或者使用FragmentManager 的addFragment或者replaceFrament 动态载入。在这种情况下,只要监听Fragment的onResume和onPause方法就能够判断其显隐。在onResume和onPause中间是对用户可见的.

@Override
public void onResume() {
    super.onResume();
    //TODO now visible to user
}
@Override
public void onPause() {
    super.onPause();
    //TODO now invisible to user
}

使用show和hide来显隐的Fragment

FragmentManager除了addFragment和replaceFragment之外还有showFragment和hideFragment来做Fragment的显隐,这样可以提生页面切换的速度,是一种用空间换时间的方式。但是这样使用的Fragment在被hide的时候是不会调用onPause方法的。因为它只是在屏幕中不可见了,但是没有Pause。这时候我们需要监听onHiddenChanged方法

@Override
public void onHiddenChanged(boolean hidden) {
    super.onHiddenChanged(hidden);
	if(hidden){
		//TODO now visible to user
	} else {
		//TODO now invisible to user
	}
}

但是我们需要注意一点,那就是,如果用户直接按home键退出了,我们的程序也没有对按home键事件进行监听,在按home键时调用hideFragment,那么onHiddenChanged事实上没有被调用,反而是onPause被调用了。所以我们需要针对这样的情况做特殊的处理。比如在home键退出时显示调用一下hideFragment或者在onPause中也发信号说本Fragment不可见了,这都是可以的。

在ViewPager中的Fragment

现在安卓市场上基本上的app都会做tab页,而tab页基本都是通过android自带的ViewPager实现的。ViewPager有这样一个特点,当滑到某一个Tab时,它会同时加载这个tab的左右两个tab页,比如我从1页面切换到了2页面,那么3页面的onResume也被调用了,但是3页面其实对用户是不可见的。这时候我们就需要监听setUserVisibleHint来判断到底对用户是否可见。

@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
    super.setUserVisibleHint(isVisibleToUser);
	if(isVisibleToUser){
		//TODO now it‘s visible to user
	} else {
		//TODO now it‘s invisible to user
	}
}

但是与第二条类似,我们依然不能完全依赖setUserVisibleHint这个方法来判断是否ViewPager中的页面是否对用户可见。因为该方法只有在Fragment切换的时候被调用。比如我从一个含有ViewPager的Actvity跳转到另一个activity,ViewPager中的Fragment的 setUserVisibleHint方法是不会被调用的,只能通过onPause来判断。进入该Activity原理类似。那么怎么办呢,我们需要结合setUserVisibleHint和onResume和onPause。

@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
    super.setUserVisibleHint(isVisibleToUser);
    if ((isVisibleToUser && isResumed())) {
        onResume();
    } else if (!isVisibleToUser) {
        Timber.i("On Pause on %s Fragment Invisble", getClass().getSimpleName());
        onPause()
    }
}
 @Override
public void onResume() {
    super.onResume();
    if (getUserVisibleHint()) {
        Timber.i("On Resume on %s Fragment Visible", getClass().getSimpleName());
		//TODO give the signal that the fragment is visible
    }
}

@Override
public void onPause() {
    super.onPause();
	//TODO give the signal that the fragment is invisible
}

需要注意以上方法并不完美,Fragment不可见的信号会被多次发送。目前还没找到一个只发送一次的方法。如果读者有更好的解决方案,欢迎跟我交流。

时间: 2024-08-19 09:08:08

如何判断Fragment是否对用户可见的相关文章

图解js中常用的判断浏览器窗体、用户屏幕可视区域大小位置的方法

有时我们需要获得浏览器窗口或屏幕的大小.窗口下拉框下拉的距离等数据,对应这些需求,js中提供了不少解决方法,只是数量稍多容易混淆它们各自的意义,下面咱们用图例来解释下12个常见对象属性的作用. 其中有6个常用的浏览器窗体属性(由于offsetWidth/Height在不同浏览器下表现有出入,故不在本章讨论): document.documentElement.clientWidth document.documentElement.clientHeight document.documentEl

实战:判断mysql中当前用户的连接数-分组筛选

#connets.sh #!/bin/sh #[email protected] #根据输入参数u或d来显示出对应的用户名或数据库名中用户的连接数. #也可以输入u 具体用户名或d 具体数据库名做进一步的分组筛选 #set mysql evn MYSQL_USER=system  #mysql的用户名 MYSQL_PASS='password'  #mysql的登录用户密码 MYSQL_HOST=192.168.2.188 export black='\033[0m' export boldbl

WinForm中如何判断关闭事件来源于用户点击右上角的“关闭”按钮

在C#的WinForm程序中,有的时候需要判定关闭请求从哪里发出来的.比如是用户点击了右上角的“关闭”按钮,还是调用了WinForm.Close()方法.最典型的是要知道点击右上角的“关闭”按钮发出的事件.下面这个方法可以判断这点: 程序代码 protected override void WndProc(ref Message msg) {         const int WM_SYSCOMMAND = 0x0112;         const int SC_CLOSE = 0xF060

如何判断Fragment是否展示

在android 开发中使用Fragment基本上是一个搞android的都知道的,他不知道方便了开发者模块化应用,而且方便开发者管理他的生命周期.但是我们很多人都是把Fragment 放到ViewPager中进行展示,让他达到更好的效果,可以滑动,可以点击切换,但是ViewPager 总是会加载当前页的前后俩页数据,那么也就会调用到其他Fragment的生命周期,可能达不到你预期的效果,如果你能知道你的Fragment什么时候展示给用户那么你就能进行一些操作来避免下.,也可以进行程序性能的优化

利用shell实现判断局域网内在线用户有那些

#!/bin/bash while true; do   for I in {100..120};do     ping -c 2 -w 2 192.168.0.$I &>/dev/null     if [ $? -eq 0 ];then       echo -e "\033[32;40m 192.168.0.$I is UP.\033[0m"     else       echo -e "\033[32;40m 192.168.0.$I is DOWN.

判断当前系统登录用户_shell脚本

#!/bin/bash#user=`whoami`if [ "$user" == "root" ];then    echo "root is super user"else    echo "$user is a normal user"fi

判断用户的用户名和其基本组的组名是否一致

#!/bin/bash #传递一个用户名参数给脚本,判断此用户的用户名跟其基本组的组名是否一致,并将结果显示出来 #判断是否传递一个参数 if [ ! $# -eq 1 ]; then echo "Usage:./group.sh ARG" exit 1 fi #判断是否存在该用户 id $1 &> /dev/null if [ ! $? -eq 0 ]; then echo "$1 not exits." exit 1 fi #取给定用户所属基本组i

4.Shell 判断用户的参数

1.Shell 判断用户的参数 系统在执行mkdir命令时会判断用户输入的信息,即判断用户指定的文件夹名称是否已经存在,如果存在则提示报错:反之则自动创建. Shell脚本中的条件测试语法可以判断表达式是否成立,若条件成立则返回数字0,否则便返回其他随机数值. 条件测试语法:的执行格式如图4-16所示.切记,条件表达式两边均应有一个空格 按照测试对象来划分,条件测试语句可以分为4种: 文件测试语句: 逻辑测试语句: 整数值比较语句: 字符串比较语句. 文件测试即使用指定条件来判断文件是否存在或权

Android Fragment 的使用,一些你不可不知的注意事项

Fragment,俗称碎片,自 Android 3.0 开始被引进并大量使用.然而就是这样耳熟能详的一个东西,在开发中我们还是会遇见各种各样的问题,层出不穷.所以,是时候总结一波了. Fragment 简介 作为 Activity 界面的一部分,Fragment 的存在必须依附于 Activity,并且与 Activity 一样,拥有自己的生命周期,同时处理用户的交互动作.同一个 Activity 可以有一个或多个 Fragment 作为界面内容,并且可以动态添加.删除 Fragment,灵活控