问题不大,是个很小的问题,两三个月前就写好了文章,但是现在才想起来发布。
这段时间在搞沉浸式状态栏,虽然时间上已经很out了,但是比不上项目的老旧,唉。第一步,先扒拉扒拉项目呗,没想到还真让我看到项目中已经引入过一个状态栏工具类,引入的人还把git链接放上去了,好人~!
看看这个项目,8k的Star,1.6k的Fork,真的感觉到柠檬树上柠檬果,柠檬树下你和我。这让我想起中午的柠檬鸡排,又酸,又菜鸡。下个demo,只能感觉一个流畅,除了正常的 Activity
, DrawerLayout & Fragment
两个常用布局也有demo演示,issue中多次提到的切换状态栏字体颜色也有演示。
人家写的不错,放到项目中也要会用才行,先整一个demo玩玩,一切完美。。。我这是不是有那么一丢丢问题,好像是个问题。唉,闲聊结束正文开始。
-
问题现象:
状态栏盖住了页面顶部大约一个状态栏高度的内容,正常状态页面内容应该在状态栏下方。因为是demo所以没有设置全屏展示,但根据
activity
跑到了状态栏下方,顶部的一部分view被状态栏盖住,因此猜测问题,在状态栏工具类里废话,你这个demo一共两个类,一个activity,一个StatusBarUtil,activity算上import不到三十行代码,问题肯定出在状态栏工具类里。。。
-
问题定位:
-
因为问题出现在尝试切换状态栏文字时,所以先尝试注释掉新增代码
StatusBarUtil.setLightMode(this)
,之后运行发现,页面展示正常,OK,看看这个方法的源码@TargetApi(Build.VERSION_CODES.M) public static void setLightMode(Activity activity) { setMIUIStatusBarDarkIcon(activity, true); setMeizuStatusBarDarkIcon(activity, true); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { activity.getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN); } } @TargetApi(Build.VERSION_CODES.M) public static void setDarkMode(Activity activity) { setMIUIStatusBarDarkIcon(activity, false); setMeizuStatusBarDarkIcon(activity, false); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { activity.getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN); } }
-
因为测试机是自己的华为手机,所以MIUI适配和Meizu适配直接跳过,问题应该就是出在
setSystemUiVisibility()
这个方法中了。这个方法虽然自己开发时没用过,但是FULLSCREEN这个单词感觉很贴近实际展示问题啊,感觉问题就是出在这里了。
-
-
修复问题:
-
看了下两个方法的区别,在于
SYSTEM_UI_FLAG_LIGHT_STATUS_BAR
这个属性,这个属性的值为0x00002000,也就是只有一个位为1的一个整形,少许读过几段源码的直觉告诉我,这个地方肯定是用位运算处理的,然后看了下SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
也是只有一个位为1的一个整形,emmm,我有个大胆的想法。 -
问题原因在于直接调用
setSystemUiVisibility()
方法进行设置会破坏掉之前页面的样式,那么第一步就先去去取出之前的mSystemUiVisibility。int visibility = activity.getWindow().getDecorView().getSystemUiVisibility();
-
虽然问题在于非
FULLSCREEN
页面被改成FULLSCREEN
页面样式,但是根据单一职责原则这个方法应该只去处理LIGHT_STATUS_BAR
的问题。只要mSystemUiVisibility修改时不涉及到FULLSCREEN
对应的位就可以了。所以对这个方法开始改进@TargetApi(Build.VERSION_CODES.M) public static void setLightMode(Activity activity) { setMIUIStatusBarDarkIcon(activity, true); setMeizuStatusBarDarkIcon(activity, true); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { int visibility = activity.getWindow().getDecorView().getSystemUiVisibility(); if (visibility != (visibility | View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR)) { visibility = visibility | View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR; } activity.getWindow().getDecorView().setSystemUiVisibility(visibility); } } @TargetApi(Build.VERSION_CODES.M) public static void setDarkMode(Activity activity) { setMIUIStatusBarDarkIcon(activity, false); setMeizuStatusBarDarkIcon(activity, false); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { int visibility = activity.getWindow().getDecorView().getSystemUiVisibility(); if (visibility == (visibility | View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR)) { visibility = visibility ^ View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR; } activity.getWindow().getDecorView().setSystemUiVisibility(visibility); } }
-
-
问题验证:
ok,一切恢复正常