Android全屏沉浸式应用
来源:互联网 发布:lsv软件 编辑:程序博客网 时间:2024/04/26 05:27
原文出处:http://bbs.itheima.com/thread-298355-1-1.html?zztj3?rss
一、概念
首先让我们看一下默认状态栏的显示效果 以下以微信与qq为例:
由于Android 系统自4.2 开始 UI 上就没多大改变,而4.4增加了透明状态栏与导航栏的功能如以下图的效果。
从以上的图可以看出Activity的contentView( 即setContentView设置的视图)可以延伸到statusBar下方 这种体验就叫沉浸式体验。这个是从用户的角度来感受的。如果从设计师的角度来看就是Immersive Mode 全浸模式,Translucent Bars 半透明状态栏。不同共同的特点就是“将布局内容延伸到手机状态栏”。
对于这种显示效果又有以下两种模式
1、全屏( ContentView 可以进入状态栏)
2、非全屏 ( ContentView 与状态栏分离, 状态栏直接着色
二、案例分析
sdk5.x以上 ,准备5.0模拟器
非全屏幕:theme默认主题着色状态栏
根据5.0以上的theme配置要求。只需配置colorPirmary(标题栏颜色),colorPrimaryDark(手机状态栏颜色)即可.
在values/styles.xml创建主题
<resources> <!--应用的基本主题 --> <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar"> <!-- 自定义应用主题 --> <!--标题颜色--> <item name="colorPrimary">@color/colorPrimary</item> <!--状态栏颜色--> <item name="colorPrimaryDark">@color/colorPrimaryDark</item> <!--text /checkBox颜色--> <item name="colorAccent">@color/colorAccent</item> </style></resources>
在systembar/src/main/AndroidManifest.xml引用
<application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:supportsRtl="true" android:theme="@style/AppTheme"> <!-这里是activity -></application>
运行效果
非全屏幕:Javacode着色状态栏
代码位置:com.example.systembar.CodeActivity
1、先写版本判断
2、直接调用setStatusBarColor
Activity activity = this;int color=Color.parseColor("#008000");//针对版本5.x以上的即LOLLIPOP以上的if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { //非全屏幕修改状态栏颜色 Window window = activity.getWindow(); //FLAG_TRANSLUCENT_STATUS为状态栏类型:半透明效果 //取消设置透明状态栏,使 ContentView 内容不再覆盖状态栏 window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS); //需要设置这个 flag 才能调用 setStatusBarColor 来设置状态栏颜色 //FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS为状态栏类型:支持着色 window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS); //设置状态栏颜色 setStatusBarColor要求21以上 window.setStatusBarColor(color); ViewGroup contentView = (ViewGroup) activity.findViewById(Window.ID_ANDROID_CONTENT); View childView = contentView.getChildAt(0);//对应activity布局文件根标签 if (childView != null) { //注意不是设置 ContentView 的 FitsSystemWindows, 而是设置 ContentView 的第一个子 View . 预留出系统 View 的空间. ViewCompat.setFitsSystemWindows(childView, true); }}
运行效果:根据标题颜色着色
android:fitsSystemWindowssetFitsSystemWindows()
所有实现 Translucent System Bar 效果的Activity,都需要在根布局里设置 android:fitsSystemWindows=”true” 。设置了该属性的作用在于,不会让系统导航栏和我们app的UI重叠,导致交互问题.以下给出效果图说明该属性。
全屏幕:contentview延伸
代码位置:com.example.systembar.CodeFullActivity#onCreate
//去掉titlebar-全屏模式supportRequestWindowFeature(Window.FEATURE_NO_TITLE);//细节supportRequestWindowFeature一定要在setContentView之前设置setContentView(R.layout.activity_code_full);Activity activity = this;int statusColor = Color.parseColor("#008000");//针对版本5.x以上的即LOLLIPOP以上的if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { Window window = activity.getWindow(); //设置透明状态栏,这样才能让 ContentView 向上 window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS); //需要设置这个 flag 才能调用 setStatusBarColor 来设置状态栏颜色 window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS); //设置状态栏颜色 window.setStatusBarColor(statusColor); ViewGroup mContentView = (ViewGroup) activity.findViewById(Window.ID_ANDROID_CONTENT); View mChildView = mContentView.getChildAt(0); if (mChildView != null) { //注意不是设置 ContentView 的 FitsSystemWindows, 而是设置 ContentView 的第一个子 View . // 使其不为系统 View 预留空间.不预留空间的话 状态栏就会覆盖布局顶部 ViewCompat.setFitsSystemWindows(mChildView, false); }}
运行效果
4.4以上,准备4.4模拟器
5.x以上的实现方式不使4.4以上的生效.所以要考虑一下兼容方案。
全屏幕:contentview延伸
思路:暂时保存标题栏时可以清楚得看到只要将contentView延伸到statusbar下方.它与statusBar共同放在一个FrameLayout里
代码位置:com.example.systembar.CodeFullActivity#onCreate
1、获取系统statusBar的高度
private static final String STATUS_BAR_HEIGHT_RES_NAME = "status_bar_height";public static int getStatusBarHeight(Context context) { int result = 0; //访问android.jar内的dimen中包含的status_bar_height属性值 int resourceId = context.getResources().getIdentifier(STATUS_BAR_HEIGHT_RES_NAME, "dimen", "android"); if (resourceId > 0) { result = context.getResources().getDimensionPixelSize(resourceId); } return result;}
2、设置无标题栏
//去掉titlebar-全屏模式supportRequestWindowFeature(Window.FEATURE_NO_TITLE);//细节supportRequestWindowFeature一定要在setContentView之前设置setContentView(R.layout.activity_code_full);
3、设置 contentView的marginTop上移状态栏高度
//KITKAT为4.4sdk的名称if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { Window window = activity.getWindow(); ViewGroup contentView = (ViewGroup) activity.findViewById(Window.ID_ANDROID_CONTENT); //首先使 ChildView 不预留空间 View childView = contentView.getChildAt(0);//layout file对应的根标签 if (childView != null) { //此时status会遮盖contnetview ViewCompat.setFitsSystemWindows(childView, false); } int statusBarHeight = getStatusBarHeight(activity); //需要设置这个 flag 才能设置状态栏 window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS); //避免多次调用该方法时,多次移除了 View if (childView != null && childView.getLayoutParams() != null && childView.getLayoutParams().height == statusBarHeight) { //移除假的 View. contentView.removeView(childView); childView = contentView.getChildAt(0); } if (childView != null) { FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) childView.getLayoutParams(); //清除 ChildView 的 marginTop 属性 if (lp != null && lp.topMargin >= statusBarHeight) { //减少layout的topmargin 使用layout布局的整体延伸到statusBar下方 lp.topMargin -= statusBarHeight; childView.setLayoutParams(lp); } }}
Deug下可以查看到
activity.findViewById(Window.ID_ANDROID_CONTENT);获取的是存放layout的FrameLayout具体类型为ContentFrameLayout
Layout的内容可以从 contentView.getChildAt(0);获取
在状态栏透明的情况下 lp.topMargin -= statusBarHeight;可以使用layout上移
运行效果
非全屏幕:Javacod着色状态栏
- 获取系统状态栏高度(同上)
- 在状态栏透明情况下下移contnetView 距离为状态栏高度
- 如果存在着色View则修改背景色
- 如果不存在着色View则添加同时设置背景色
//判断当前sdk是4.4 KITKAT为4.4sdk的名称 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { Window window = activity.getWindow(); ViewGroup contentView = (ViewGroup) activity.findViewById(Window.ID_ANDROID_CONTENT); //设置状态栏透明 window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS); //获取状态栏高度 int statusBarHeight = getStatusBarHeight(activity); //在全屏模式下 使用contentView内容下移状态栏高度 View childView = contentView.getChildAt(0); if (childView != null) { FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) childView.getLayoutParams(); //如果已经为 ChildView 设置过了 marginTop, 再次调用时直接跳过 if (lp != null && lp.topMargin < statusBarHeight && lp.height != statusBarHeight) { //不预留系统空间 ViewCompat.setFitsSystemWindows(childView, false); lp.topMargin += statusBarHeight;//在状态栏透明的情况下 contentView marginTop改为状态栏高度 childView.setLayoutParams(lp); } } //下移的状态栏高度 已经存在着色View直接设置color View statusBarView = contentView.getChildAt(0); if (statusBarView != null && statusBarView.getLayoutParams() != null && statusBarView.getLayoutParams().height == statusBarHeight) { //避免重复调用时多次添加已经着色的View statusBarView.setBackgroundColor(statusColor); }else { //如果未存在刚添加着色View下次通过contentView.getChildAt(0);即为该着色View statusBarView = new View(activity); ViewGroup.LayoutParams lp = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, statusBarHeight); statusBarView.setBackgroundColor(statusColor); //向 ContentView 中添加已经着色的View contentView.addView(statusBarView, 0, lp); } }}
运行效果,我在此处添加的着色View背景为绿色
此时还可以去掉系统自带的标题栏
【源代码】http://pan.baidu.com/s/1slOj6sl
开源第三方SystemBarTint
下面介绍一个将以上过程封装比较到位的第三方开源状态栏工具库
支持4.4以上
Github地址:https://github.com/Ztiany/SystemBarTint
运行效果
4.4以上
5.x以上
在android5.0以上
<style name="AppBaseTheme" parent="Theme.AppCompat.Light.NoActionBar"> <item name="colorPrimary">@color/titleBlue</item> <item name="colorPrimaryDark">#3A5FCD</item> <item name="@android:textColorPrimary">@android:color/white</item> </style> <style name="AppTheme" parent="AppBaseTheme"> <!-- 隐藏标题栏 --> <item name="android:windowNoTitle">true</item> <item name="android:windowDrawsSystemBarBackgrounds">true</item> <item name="android:statusBarColor">@color/transparent</item> <!--<item name="colorControlNormal">@color/white</item>--> </style>
当statusBarColor设置为透明色后,状态栏的颜色为白色,如果布局文件加上属性android:fitsSystemWindows=”true”后,状态栏则显示colorPrimaryDark颜色
styles(4.0之前)
<!-- 半透明的主题样式 --> <style name="NavigationTransparent" parent="AppTheme"> <!-- Android 4.4 之前的版本跟随系统默认的样式--> </style>
styles(4.4之后)
<!-- 半透明的主题样式 --> <style name="NavigationTransparent" parent="AppTheme"> <!-- 状态栏 半透明 --> <item name="android:windowTranslucentStatus">true</item> <!-- 导航栏 半透明--> <item name="android:windowTranslucentNavigation">true</item> </style>
styles(5.0之后)
<!-- 半透明的主题样式 --> <style name="NavigationTransparent" parent="AppTheme"> <!-- 导航栏 半透明--> <item name="android:windowTranslucentNavigation">true</item> <!-- 状态栏 半透明 --> <item name="android:windowTranslucentStatus">true</item> <!-- Android 5.0开始需要把颜色设置为透明。否状态栏会用系统默认的浅灰色 (Android 5.0以后支持修改颜色,需指定颜色)--> <item name="android:statusBarColor">@android:color/transparent</item> </style>
- Android全屏沉浸式应用
- 全屏沉浸式应用
- Android 沉浸式全屏
- Android开发UI之全屏沉浸式应用
- Android 沉浸式全屏的实现方法
- Android 沉浸式全屏的实现方法
- Android 沉浸式全屏的实现方法
- 沉浸式全屏模式(Android 4.4)
- android 使用全屏沉浸模式
- Android状态栏沉浸式模式下全屏、修改颜色
- Android UI体验之全屏沉浸式透明状态栏效果
- Android UI体验之全屏沉浸式透明状态栏效果
- Android-踩坑之路-全屏-沉浸式
- Android UI体验之全屏沉浸式透明状态栏样式
- Android 应用使用沉浸式状态栏
- android沉浸式应用(模式)
- Android全屏模式,沉浸模式。粘性沉浸模式
- Android 沉浸式 完全沉浸
- #include <head.h>与#include "head.h"的区别
- HDU 5903 Square Distance
- 【JZOJ 4798】天使的分裂
- spring学习(官网)——解决版本冲突问题
- ul li datalist控件导航栏动态绑定数据库,并且显示相应的内容
- Android全屏沉浸式应用
- 观察者模式
- 玲珑杯 1009 Spoon Devil's Bucket 矩阵优化DP
- 总结:关于字符串长度的问题
- 浅谈HSSF的单元格合并与cell样式
- 光场相机预处理 TFTOOLBOX
- FFT+NTT 学习资料收集
- HDU 1227 Fast Food(dp)
- ASM存储管理