Android 沉浸式状态栏总结
来源:互联网 发布:与泰国人聊天软件 编辑:程序博客网 时间:2024/05/21 20:30
在 Android4.4 之后,Android Window支持了一些新的属性,其中有两个是这样的 .
WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUSWindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION
正如它们的变量名的意思,使用这两个属性,可以使得状态栏和导航栏变为透明,导航栏指的就是Android下方的三大按键,当然只使用第一个属性也可以达到今天所要完成的效果。下面的示例代码将使状态栏和导航栏变得透明@Overrideprotected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); initWindow();}
@TargetApi(19)private void initWindow(){ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT){ getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS); getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION); }
或者对主题设置(注意对 values 资源的限定,仅用于 API19 及以上): <item name="android:windowTranslucentNavigation">true</item> <item name="android:windowTranslucentStatus">true</item>
在使用沉浸式主题是,布局会往上移,如图
Flyme4.2 Android4.4.4上运行效果
这个问题也很好解决,有2个解决方案
1.在 style theme 添加
<item name="android:fitsSystemWindows">true</item> 有bug,布局中的Padding会失效
布局时是否考虑给系统窗口留出空间,true为留出空间(如 Status Bar and App bar)
2.计算状态栏的高度,为每个RootView设置Padding (推荐使用这个方法,因为fitsSystemWindows会产生比较多的问题,如Toast弹出位置也会往上移,最外层Padding也会失效)
public int getStatusBarHeight() { int result = 0; int resourceId = getResources().getIdentifier("status_bar_height", "dimen", "android"); if (resourceId > 0) { result = getResources().getDimensionPixelSize(resourceId); } return result; }
之后我们再运行,却又发现,状态栏的位置出来了,但是。。。
实际上,状态栏已经透明了,只是状态栏底下没有颜色呀!
Google 了之后在 Github 找到了一个开源项目 SystemBarTint ,代码就变成下面这个样子:
private SystemBarTintManager tintManager; @TargetApi(19) private void initWindow(){ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT){ getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS); getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION); tintManager = new SystemBarTintManager(this); tintManager.setStatusBarTintColor(getColor(R.color.app_main_color)); tintManager.setStatusBarTintEnabled(true); } }
运行之后,发现运行效果跟第一张图一样,达到我们想要的效果了。
跟踪进去查看 SystemBarTint 的源代码,会发现 SystemBarTintManager 的构造方法里面除了获取 ActionBar 的高度等等这些配置之外,还有一个重要的方法 setupStatusBarView
@TargetApi(19) public SystemBarTintManager(Activity activity) { Window win = activity.getWindow(); ViewGroup decorViewGroup = (ViewGroup) win.getDecorView(); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { //省去部分代码... if (mStatusBarAvailable) { setupStatusBarView(activity, decorViewGroup); } if (mNavBarAvailable) { setupNavBarView(activity, decorViewGroup); } }
于是接着查看 setupStatusBarView 的代码
private void setupStatusBarView(Context context, ViewGroup decorViewGroup) { mStatusBarTintView = new View(context); LayoutParams params = new LayoutParams(LayoutParams.MATCH_PARENT, mConfig.getStatusBarHeight()); params.gravity = Gravity.TOP; if (mNavBarAvailable && !mConfig.isNavigationAtBottom()) { params.rightMargin = mConfig.getNavigationBarWidth(); } mStatusBarTintView.setLayoutParams(params); mStatusBarTintView.setBackgroundColor(DEFAULT_TINT_COLOR); mStatusBarTintView.setVisibility(View.GONE); decorViewGroup.addView(mStatusBarTintView); }
可以发现这个开源项目能够解决我们的问题的原因在这,就是往 DecorView 加入一个 View, 而在代码中我们将这个 View 的背景设置成 ActionBar 一样的颜色,所以就达到了沉浸式的效果。到这里,基本也就分析完成了。
附上源代码地址: Github 源代码 .
- 一个已知的BUG
沉浸式状态栏的一个BUG, 导致在软键盘弹出后页面没有resize,内容被键盘遮住,adjustPan不起作用,如写说说、写日志这些界面。直接在需要relayout的子view上添加fitsSystemWindows属性。
- 状态栏高度不一致
部分rom(如miui和Flyme等)修改了状态栏高度,miui改高了,而meizu上的flyme则改矮了,所以不能直接写作25dp。在CustomTitleBar组件中通过重写getPaddingTop方法来兼容所有状态栏高度。
- 很多rom把渐变阴影给去了(CM、miui、Flyme OS等等)
大部分应用了沉浸式状态栏的应用都没有考虑到这点,如腾讯地图,导致在那些rom上打开应用后状态栏一片白乎乎的看不清。
尽管google的原生4.4 rom中,在设置了沉浸式状态栏后,会对状态栏区域加上一条渐变的背景,来防止亮色导致状态栏图标/字看不清,但实际应用中发现其实很多rom把渐变阴影给去了,所以在状态栏组件中,加上了绘制阴影的选项(包括5.0半透明黑条和4.4渐变阴影两种选项),会在4.4机器开启了沉浸式状态栏时,绘制阴影。小米 的MIUI6解决方案 : MIUI 6 沉浸式状态栏调用方法
- fitsSystemWindows 设置为true,Toast文本显示偏上方什么鬼?
- 不要设置Activity的theme的fitsSystemWindows为true
- 或者使用getApplicationContext()
相关链接:
http://www.jianshu.com/p/f8374d6267ef
http://blog.csdn.net/marktheone/article/details/46663035
http://codersimple.github.io/android/2015/05/15/immersive-theme-for-android.html
点击下载我的Demo源码
下面了解各种状态栏的定义
---------------------------------------------------------------------------------------------------
状态栏变色龙
- 沉浸式:全屏模式,通知栏隐藏,即全屏,部分应用打开时会出现
- 沉浸式状态栏
- 变色龙式状态栏:将状态栏本身的背景全透明化,同时改变应用窗口顶部的颜色。这样能在切换应用窗口时,完成同步变色,并且将色彩一体感做得比原生系统更彻底。既保证顶栏应用图标和文字清晰显示,又将顶栏的颜色与下部的颜色无缝连接起来。将动静态之间的效果调整恰当,让整体的视觉显得流畅。
- 透明通知栏:MIUI V5这类的老系统,虽然是Android4.2,但是桌面还是能透明的。
在静态画面展示上,变色龙却优于原生沉浸式。变色龙在静态画面中的颜色是一体化的,而原生沉浸式的顶栏的会增加一层阴影,用来突出状态栏处白色的文字和图标,但这使得原生沉浸式在静态画面中呈现出割裂感,带来的视觉体验不是很好。
透明状态栏示例:
- Android 沉浸式状态栏总结
- Android关于沉浸式状态栏总结
- Android 沉浸式状态栏
- android 沉浸式 状态栏
- android 沉浸式状态栏
- android沉浸式状态栏
- Android沉浸式状态栏
- Android 沉浸式状态栏
- android 沉浸式状态栏
- Android沉浸式状态栏
- Android沉浸式状态栏
- Android 沉浸式状态栏
- Android沉浸式状态栏
- android 沉浸式状态栏
- android 沉浸式状态栏
- Android沉浸式状态栏
- android沉浸式状态栏
- Android 沉浸式状态栏
- iOS/OS X开发:各种工具快到碗里来
- ffmpeg入门小结(一)—— YUV格式示例
- Android自定义控件——自定义属性
- Android通过代码进行多屏幕适配
- 栈的压入、弹出序列
- Android 沉浸式状态栏总结
- 关于连接多个数据库的问题
- Item 36:不要重写继承来的非虚函数
- Python之从零开始:本博规划
- C++如何避免使用rand() % xxx的方式实现类似抽奖概率类的问题
- HIVE Exception in thread "main" java.lang.IncompatibleClassChangeError: Found class jline.Terminal,
- sed在shell中的简单应用
- centos 定时任务Crontab 使用实例
- Study schedule for new work.