zoukankan      html  css  js  c++  java
  • 如何判断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不可见的信号会被多次发送。目前还没找到一个只发送一次的方法。如果读者有更好的解决方案,欢迎跟我交流。

  • 相关阅读:
    python json 和 pickle的补充 hashlib configparser logging
    go 流程语句 if goto for swich
    go array slice map make new操作
    go 基础
    块级元素 行内元素 空元素
    咽炎就医用药(慢性肥厚性咽炎)
    春季感冒是风寒还是风热(转的文章)
    秋季感冒 咳嗽 怎么选药
    解决IE浏览器“无法显示此网页”的问题
    常用的 css 样式 记录
  • 原文地址:https://www.cnblogs.com/dongweiq/p/5411899.html
Copyright © 2011-2022 走看看