关于GitHub上8k-Star的一个项目的问题修复

问题不大,是个很小的问题,两三个月前就写好了文章,但是现在才想起来发布。


这段时间在搞沉浸式状态栏,虽然时间上已经很out了,但是比不上项目的老旧,唉。第一步,先扒拉扒拉项目呗,没想到还真让我看到项目中已经引入过一个状态栏工具类,引入的人还把git链接放上去了,好人~!

沉浸式状态栏Github直通车

看看这个项目,8k的Star,1.6k的Fork,真的感觉到柠檬树上柠檬果,柠檬树下你和我。这让我想起中午的柠檬鸡排,又酸,又菜鸡。下个demo,只能感觉一个流畅,除了正常的 Activity, DrawerLayout & Fragment两个常用布局也有demo演示,issue中多次提到的切换状态栏字体颜色也有演示。

人家写的不错,放到项目中也要会用才行,先整一个demo玩玩,一切完美。。。我这是不是有那么一丢丢问题,好像是个问题。唉,闲聊结束正文开始。


  1. 问题现象:

    状态栏盖住了页面顶部大约一个状态栏高度的内容,正常状态页面内容应该在状态栏下方。因为是demo所以没有设置全屏展示,但根据activity跑到了状态栏下方,顶部的一部分view被状态栏盖住,因此猜测问题,在状态栏工具类里

    废话,你这个demo一共两个类,一个activity,一个StatusBarUtil,activity算上import不到三十行代码,问题肯定出在状态栏工具类里。。。

  2. 问题定位:

    1. 因为问题出现在尝试切换状态栏文字时,所以先尝试注释掉新增代码 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);
              }
          }
      
    2. 因为测试机是自己的华为手机,所以MIUI适配和Meizu适配直接跳过,问题应该就是出在 setSystemUiVisibility()这个方法中了。这个方法虽然自己开发时没用过,但是FULLSCREEN这个单词感觉很贴近实际展示问题啊,感觉问题就是出在这里了。

  3. 修复问题:

    1. 看了下两个方法的区别,在于 SYSTEM_UI_FLAG_LIGHT_STATUS_BAR这个属性,这个属性的值为0x00002000,也就是只有一个位为1的一个整形,少许读过几段源码的直觉告诉我,这个地方肯定是用位运算处理的,然后看了下 SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN也是只有一个位为1的一个整形,emmm,我有个大胆的想法。

    2. 问题原因在于直接调用 setSystemUiVisibility()方法进行设置会破坏掉之前页面的样式,那么第一步就先去去取出之前的mSystemUiVisibility。

          int visibility = activity.getWindow().getDecorView().getSystemUiVisibility();
      
    3. 虽然问题在于非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);
              }
          }
      
  4. 问题验证:

    ok,一切恢复正常

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值