开发者社区> 技术小胖子> 正文

android状态栏总结

简介:
+关注继续查看
  1. 针对状态栏的操作,只针对4.4kitKat(含)以上的机型,部分国产rom会失效,目前发现的有华为的EMUI
  2. Activity必须是noActionbar主题
  3. 本文基于StatusBarUtils略作修改,感谢作者laobie
  4. 本文源码地址
相关属性重温
  • FitsSystemWindows
    在使用FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDSFLAG_TRANSLUCENT_STATUS挤占了状态栏的高度的时候,我们的布局文件也跟着顶到了状态栏上。通过FitsSystemWindows,系统会把app布局文件的paddingTop修改成状态栏的高度,达到适配的效果

    false顶到状态栏

true,paddingTop有一个状态栏高度
  • android.R.id.content
    通过它我们可以在不需要知道ID的情况下,访问当前Activity根节点,一般是ContentFrameLayout类型,通过((ViewGroup)findViewById(R.id.content)).getChildAt(0);可以获取到我们布局xml的根节点

  • getDecorView()
    通过他,我们可以获取到整个Window界面的最顶层View。我们用的很多的findViewById(),就是基于这个DecorView查找里面的子节点的。比如Activity主题是Theme.AppCompat.Light.NoActionBar的组织层级如下,


noActionbarView层次.png

为什么嵌套那么深,因为各个层次可能都会有几个ViewStub方便注入,只是我们现在的主题用不到就是空了。

下面开始实战了,一般我们用的比较多的是透明状态栏、设置状态栏颜色、DrawerLayout盖在状态栏上三种。

1. 透明状态栏

这种情况一般用于把图片延伸到状态栏上,图片还分两种

  1. 作为background的全屏大图
  2. 作为ImageView控件存在,一般只占屏幕高度的一部分

这两种情况下的处理方式还不一样,具体看下文

/** * 使状态栏透明 */
private static void transparentStatusBar(Activity activity) {    
     if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {       
          activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS | WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);        
          activity.getWindow().setStatusBarColor(Color.TRANSPARENT);
    } 
     else {       
          activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS | WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);   
  }
}

上面的代码针对5.0以上或者4.4以上5.0以下的机型,让其状态栏透明、导航栏半透明,效果如下:


透明状态栏的结果是布局文件顶到了状态栏上


dump了下节点信息,我们发现布局的paddingTop从(50px状态栏高度)被修改成了0px。从而让图片延伸到了状态栏


不透明状态栏.png

透明状态栏.png


这种情况下,对app布局文件通过设置FitsSystemWindows就可以完成适配了

/**
 * 获取activity的根节点
 *@param activity
 *@return
 */
public static ViewGroup getAppRootView(Activity activity) { 
   return (ViewGroup) ((ViewGroup) activity.findViewById(android.R.id.content)).getChildAt(0);
}

/**  
*将目标View的paddingTop从0设置为状态栏的高度
 */
private static void setRootViewFitSystemWindow(Activity activity) { 
   ViewGroup rootView = getAppRootView(activity);   
   rootView.setFitsSystemWindows(true);   
   rootView.setClipToPadding(true);
}

app内容布局有了padding.png


注意!!要延伸到状态栏的图片,如果不是根节点的背景图,而是一个ImageView控件,那么就不能设置setFitsSystemWindows了,原因参考上图红框。这种情况下,为了防止顶到状态栏,需要手动在xml里通过paddingTopmarginTop调整标题栏元素位置达到适配。类似下图


延伸到状态栏的图片是一个ImageView

2. 状态栏颜色

设置状态栏颜色的步骤和透明类似,差别在于5.0以下机型无法直接设置状态栏颜色,我们可以模拟一个纯色的View放到状态栏下面间接达到着色效果。放置的父层级我们选择DecorView

如果发现状态栏颜色设置无效,有可能是布局文件的root节点加了backgroundColor所致

/**
 * 
设置状态栏颜色
 *
 * @param activity       需要设置的activity
 * @param color          状态栏颜色值
 * @param statusBarAlpha 状态栏透明度
 */
public static void setColor(Activity activity, int color, int statusBarAlpha) { 
   if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT)     return; 

   if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {  
      activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);       
      activity.getWindow().setStatusBarColor(UIUtils.calcColorWithAlpha(color, statusBarAlpha));   
 } else {        
     activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);     
     ViewGroup decorView = (ViewGroup) activity.getWindow().getDecorView();        
     insertMockStatusBackgroundView(decorView, color, statusBarAlpha);  
  }    
     setRootViewFitSystemWindow(activity);
}

上面的代码判断DecorView下第0个View是不是我们自定义的StatusbarView类型,如果是则设置颜色,否则创建一个纯色控件插入到DecorView内,同时布局内容上间距腾出给纯色控件。

3. DrawerLayout盖在状态栏上

DrawerLayout主要有两个子元素1:内容View 2:侧滑栏
侧滑栏必然要在内容View后面以覆盖前者


侧滑栏效果


所以我们要做的有2步

  1. 插入纯色控件到内容View(如果不是LinarLayout需要考虑内容View元素重新排列)
  2. DrawerLayout设置fitSystemWindow=false;以覆盖到状态栏上

代码如下:

/** * 为DrawerLayout 布局设置状态栏变色
 * 
* @param activity       需要设置的activity 
* @param drawerLayout   DrawerLayout
 * @param color          状态栏颜色值
 * @param statusBarAlpha 状态栏透明度 
*/public static void setColorForDrawerLayout(Activity activity, DrawerLayout drawerLayout, int color, int statusBarAlpha) { 
   if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {        return;    }  

   if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {        
      activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);        
      activity.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);      
      activity.getWindow().setStatusBarColor(Color.TRANSPARENT);   
   } else {        
     activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS); 
   }    
     ViewGroup contentLayout = (ViewGroup) drawerLayout.getChildAt(0);    
     //如果内容view不是LinearLayout,则需要重新排列内容view子元素的内容    
     insertMockStatusBackgroundView(contentLayout, color, statusBarAlpha);    
     drawerLayout.setFitsSystemWindows(false);
}

总结:

上面三个方法,涵盖了app在大部分沉浸场景下的状态。在了解了底层实现后,我们也可以轻松在安卓上实现IOS的沉浸效果了,最低版本4.4 kitkat现在已经非常普及,随着MIUI、FlyME相继都升级到5.0、6.0以上,魅蓝、红米等大批国产中低端机型的都可以体验到这种酷炫的效果了。


    本文转自 一点点征服   博客园博客,原文链接:http://www.cnblogs.com/ldq2016/p/6671889.html,如需转载请自行联系原作者




版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
Android推送集成方案总结
刚做完推送集成方案,记录下坑。 这里记录的特性和使用时针对写blog时采用的sdk的,具体使用流程和限制还请参考官方给出的sdk. #### 1、推送规则 小米手机用小米推送; 华为手机用华为推送; 其他手机用友盟推送。
65 0
淘宝安卓端搜索架构升级总结
推荐语:这篇文章图文并茂地介绍了淘宝搜索滚动容器的技术演进过程,结合代码讲解页面结构划分、数据处理、交互效果,还包含了对逻辑抽象、功能拓展的思考,最后总结了可复用的架构。非常具有实践意义,推荐阅读学习! ——大淘宝技术终端开发工程师 门柳
76 0
Android | 老生常谈!屏幕适配原理 & 方案总结笔记
Android | 老生常谈!屏幕适配原理 & 方案总结笔记
92 0
猿创征文|Android常用知识总结
猿创征文|Android常用知识总结
61 0
关于Android SurfaceView截屏总结
关于Android SurfaceView截屏总结
667 0
Android获取启动页面Activity方法总结
我们在做Android自动化测试过程中,经常会需要获取应用的启动Activity页面信息,那么今天就来跟大家分享一下有哪些获取应用启动Activity页面信息的方法。
507 0
【原理+实战+视频+源码】6年老Android面经总结,实战篇
【原理+实战+视频+源码】6年老Android面经总结,实战篇
56 0
优秀Android程序员必知必会的网络基础,积累总结
优秀Android程序员必知必会的网络基础,积累总结
52 0
你还在把Java当成Android官方开发语言吗?积累总结
你还在把Java当成Android官方开发语言吗?积累总结
48 0
mmkv跨进程,Android开发经验的有效总结,系列篇
mmkv跨进程,Android开发经验的有效总结,系列篇
444 0
文章
问答
文章排行榜
最热
最新
相关电子书
更多
Android组件化实现
立即下载
蚂蚁聚宝Android秒级编译—— Freeline
立即下载
Android插件化:从入门到放弃
立即下载