Android判断页面是否全屏

龙旋

共 3895字,需浏览 8分钟

 ·

2021-04-08 10:25

Android 想判断 Activity 是否是全屏,网上找了些方法,看到有直接获取 flags 和一个具体的值比较,并没有用,其实分析下来也觉得应该不对。大多都是如何设置全屏和取消全屏,并没有判断是否全屏的方法。


其实全屏控制要么通过主题设置,要么代码 addFlags,最终都会到 Window 的 setFlags 方法里,下面看源码:

public void setFlags(int flags, int mask) {    final WindowManager.LayoutParams attrs = getAttributes();    attrs.flags = (attrs.flags&~mask) | (flags&mask);    mForcedWindowFlags |= mask;    dispatchWindowAttributesChanged(attrs);}


主要的逻辑就是这一句:

attrs.flags = (attrs.flags&~mask) | (flags&mask)

是位运算,看一下 attrs 里可以设置的 flag 常量

public static final int FLAG_ALLOW_LOCK_WHILE_SCREEN_ON   = 0x00000001;public static final int FLAG_DIM_BEHIND                   = 0x00000002;public static final int FLAG_BLUR_BEHIND                  = 0x00000004;public static final int FLAG_NOT_FOCUSABLE                = 0x00000008;public static final int FLAG_NOT_TOUCHABLE                = 0x00000010;public static final int FLAG_NOT_TOUCH_MODAL              = 0x00000020;public static final int FLAG_TOUCHABLE_WHEN_WAKING        = 0x00000040;public static final int FLAG_KEEP_SCREEN_ON               = 0x00000080;public static final int FLAG_LAYOUT_IN_SCREEN             = 0x00000100;public static final int FLAG_LAYOUT_NO_LIMITS             = 0x00000200;public static final int FLAG_FULLSCREEN                   = 0x00000400;public static final int FLAG_FORCE_NOT_FULLSCREEN         = 0x00000800;public static final int FLAG_DITHER                       = 0x00001000;public static final int FLAG_SECURE                       = 0x00002000;public static final int FLAG_SCALED                       = 0x00004000;public static final int FLAG_IGNORE_CHEEK_PRESSES         = 0x00008000;public static final int FLAG_LAYOUT_INSET_DECOR           = 0x00010000;public static final int FLAG_ALT_FOCUSABLE_IM             = 0x00020000;public static final int FLAG_WATCH_OUTSIDE_TOUCH          = 0x00040000;public static final int FLAG_SHOW_WHEN_LOCKED             = 0x00080000;public static final int FLAG_SHOW_WALLPAPER               = 0x00100000;public static final int FLAG_TURN_SCREEN_ON               = 0x00200000;public static final int FLAG_DISMISS_KEYGUARD             = 0x00400000;public static final int FLAG_SPLIT_TOUCH                  = 0x00800000;public static final int FLAG_HARDWARE_ACCELERATED         = 0x01000000;public static final int FLAG_LAYOUT_IN_OVERSCAN           = 0x02000000;public static final int FLAG_TRANSLUCENT_STATUS           = 0x04000000;public static final int FLAG_TRANSLUCENT_NAVIGATION       = 0x08000000;public static final int FLAG_LOCAL_FOCUS_MODE             = 0x10000000;public static final int FLAG_SLIPPERY                     = 0x20000000;public static final int FLAG_LAYOUT_ATTACHED_IN_DECOR     = 0x40000000;public static final int FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS = 0x80000000;


很明显,这些十六进制值换成二进制的话,都只有一个 1,而且每个变量的 1 处于不同的位置,所以设置一个 flag 肯定就是将 flags 的对应位置设为 1,而 clearFlags 就是将对应位置设为 0。


比如 FLAG_FULLSCREEN 值为 0x00000400,换成二进制的话后面的位就是 0100 0000 0000,它控制的是从右向左数第 11 位。而 addFlags 时两个参数 flags 和 mask 一样。所以 (attrs.flags&~mask) | (flags&mask) 的 flags&mask 自己和自己作与运算,结果还是自己,而 ~mask 结尾为 1011 1111 1111,和原来的 flags 作与运算,则第 11 位肯定变成了 0,其它位和 1 作与运算,保持原样,再和后面做或,则第 11 位又变成了 1,而且这次运算只会影响到第 11 位,其它位置不变,不管原来第 11 位是 0 还是 1,结果都会变成 1。


相似的,如果是 clearFlags,第一个参数变成 0,第二个参数是 FLAG_FULLSCREEN,这样 (flags&mask) 必定为 0,只看前面,(attrs.flags&~mask) 这个运算第 11 位必为 0。


其实 (attrs.flags&~mask) | (flags&mask) 前面的与运算会将对应位置变成 0,然后看后面的与运算,后面算出结果对应位置是 1,那最终就是 1,后面算出是 0,那最终也是 0。而后面的控制就是 0 或者自己和自己作个与运算。


说了一大堆废话,其实就是最基础的位运算。那么想判断是否全屏很简单,只要看 flags 从右向左数第 11 位是 0 还是 1,只要与 FLAG_FULLSCREEN 做个逻辑与就行了,除了第 11 位,其它位都变成了 0。


判断方法为:

if ( (getWindow().getAttributes().flags & WindowManager.LayoutParams.FLAG_FULLSCREEN)                   == WindowManager.LayoutParams.FLAG_FULLSCREEN) {    // 是全屏}


到这里就结束啦.


浏览 17
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报