求解,状态栏android沉浸式状态栏怎么弄

智能手机教程子分类教程分享:如何实现Android沉浸式状态栏——教你让你的状态栏变个色!
&& 一、概述
& & & &近期注意到QQ新版使用了沉浸式状态栏,ok,先声明一下:本篇博客效果下图:
& & & &关于这个状态栏变色到底叫「Immersive Mode」/「Translucent Bars」有兴趣可以去了解下。
& & & &恩,接下来正题。
& & & &首先只有大于等于4.4版本支持这个半透明状态栏的效果,但是4.4和5.0的显示效果有一定的差异,所有本篇博文内容为:
& & & &如何实现半透明状态栏效果在大于4.4版本之上。
& & & &如何让4.4的效果与5.0的效果尽可能一致。
& & & &看了不少参考文章,都介绍到这个库,大家可以了解:SystemBarTint。
& & & &不过本篇博文并未基于此库,自己想了个hack,对于此库源码有空再看了。
& & & &二、效果图
& & & &先贴下效果图,以便和实现过程中做下对比
& & & &4.4 模拟器
& & & 5.x 真机
& & & &ok,有了效果图之后就开始看实现了。
& & & &三、实现半透明状态栏
& & & &因为本例使用了NavigationView,所以布局代码稍多,当然如果你不需要,可以自己进行筛减。
& & & &注意引入相关依赖:
compile&'com.android.support:appcompat-v7:22.2.1'&&
compile&'com.android.support:support-v4:22.2.1'&&
compile&'com.android.support:design:22.2.0'&&
& & & (一)colors.xml 和 styles.xml
& & & &首先我们定义几个颜色:
& & & &res/values/color.xml
XML/HTML代码
&?xml&version="1.0"&encoding="utf-8"?&&&
&resources&&&
&&&&&color&name="primary"&#FF03A9F4&/color&&&
&&&&&color&name="primary_dark"&#FF0288D1&/color&&&
&&&&&color&name="status_bar_color"&@color/primary_dark&/color&&&
&/resources&&&
& & & &下面定义几个styles.xml
& & & &注意文件夹的路径:
& & & &values/styles.xml
XML/HTML代码
&resources&&&
&&&&&style&name="BaseAppTheme"&parent="Theme.AppCompat.Light.NoActionBar"&&&
&&&&&&&&&!--&Customize&your&theme&here.&--&&&
&&&&&&&&&item&name="colorPrimary"&@color/primary&/item&&&
&&&&&&&&&item&name="colorPrimaryDark"&@color/primary_dark&/item&&&
&&&&&&&&&item&name="colorAccent"&#FF4081&/item&&&
&&&&&/style&&&
&&&&&!--&Base&application&theme.&--&&&
&&&&&style&name="AppTheme"&parent="@style/BaseAppTheme"&&&
&&&&&/style&&&
&/resources&&&
& & & &values-v19
XML/HTML代码
&resources&&&
&&&&&style&name="AppTheme"&parent="@style/BaseAppTheme"&&&
&&&&&&&&&item&name="android:windowTranslucentStatus"&true&/item&&&
&&&&&/style&&&
&/resources&&&
& & & &ok,这个没撒说的。注意我们的主题是基于NoActionBar的,android:windowTranslucentStatus这个属性是v19开始引入的。
& & & (二)布局文件
& & & &activity_main.xml
XML/HTML代码
&android.support.v4.widget.DrawerLayout&&
&&&&xmlns:android="/apk/res/android"&&
&&&&xmlns:app="/apk/res-auto"&&
&&&&xmlns:tools="/tools"&&
&&&&android:layout_width="match_parent"&&
&&&&android:layout_height="match_parent"&&
&&&&&LinearLayout&&
&&&&&&&&android:id="@+id/id_main_content"&&
&&&&&&&&android:layout_width="match_parent"&&
&&&&&&&&android:layout_height="match_parent"&&
&&&&&&&&android:orientation="vertical"&&&
&&&&&&&&&android.support.v7.widget.Toolbar&&
&&&&&&&&&&&&android:id="@+id/id_toolbar"&&
&&&&&&&&&&&&android:layout_width="match_parent"&&
&&&&&&&&&&&&android:layout_height="wrap_content"&&
&&&&&&&&&&&&android:background="?attr/colorPrimary"&&
&&&&&&&&&&&&android:fitsSystemWindows="true"&&
&&&&&&&&&&&&app:popupTheme="@style/ThemeOverlay.AppCompat.Light"/&&&
&&&&&&&&&TextView&&
&&&&&&&&&&&&android:id="@+id/id_tv_content"&&
&&&&&&&&&&&&android:layout_width="match_parent"&&
&&&&&&&&&&&&android:layout_height="0dp"&&
&&&&&&&&&&&&android:layout_weight="1"&&
&&&&&&&&&&&&android:gravity="center"&&
&&&&&&&&&&&&android:text="HelloWorld"&&
&&&&&&&&&&&&android:textSize="30sp"/&&&
&&&&&/LinearLayout&&&
&&&&&android.support.design.widget.NavigationView&&
&&&&&&&&android:id="@+id/id_nv_menu"&&
&&&&&&&&android:layout_width="match_parent"&&
&&&&&&&&android:layout_height="match_parent"&&
&&&&&&&&android:layout_gravity="start"&&
&&&&&&&&android:fitsSystemWindows="true"&&
&&&&&&&&app:headerLayout="@layout/header_just_username"&&
&&&&&&&&app:menu="@menu/menu_drawer"&&
&&&&&&&&/&&&
&/android.support.v4.widget.DrawerLayout&&&
& & & &DrawerLayout内部一个LinearLayout作为内容区域,一个NavigationView作为菜单。&
& & & &注意下Toolbar的高度设置为wrap_content。
& & & &然后我们的NavigationView中又依赖一个布局文件和一个的文件。
& & & &header_just_username.xml
XML/HTML代码
&?xml&version="1.0"&encoding="utf-8"?&&&
&RelativeLayout&xmlns:android="/apk/res/android"&&
&&&&&&&&&&&&&&&&android:layout_width="match_parent"&&
&&&&&&&&&&&&&&&&android:layout_height="192dp"&&
&&&&&&&&&&&&&&&&android:background="?attr/colorPrimaryDark"&&
&&&&&&&&&&&&&&&&android:orientation="vertical"&&
&&&&&&&&&&&&&&&&android:padding="16dp"&&
&&&&&&&&&&&&&&&&android:fitsSystemWindows="true"&&
&&&&&&&&&&&&&&&&android:theme="@style/ThemeOverlay.AppCompat.Dark"&&&
&&&&&TextView&&
&&&&&&&&android:id="@+id/id_link"&&
&&&&&&&&android:layout_width="wrap_content"&&
&&&&&&&&android:layout_height="wrap_content"&&
&&&&&&&&android:layout_alignParentBottom="true"&&
&&&&&&&&android:layout_marginBottom="16dp"&&
&&&&&&&&android:text="http://blog.csdn.net/lmj"/&&&
&&&&&TextView&&
&&&&&&&&android:id="@+id/id_username"&&
&&&&&&&&android:layout_width="wrap_content"&&
&&&&&&&&android:layout_height="wrap_content"&&
&&&&&&&&android:layout_above="@id/id_link"&&
&&&&&&&&android:text="Zhang&Hongyang"/&&&
&&&&&ImageView&&
&&&&&&&&android:layout_width="72dp"&&
&&&&&&&&android:layout_height="72dp"&&
&&&&&&&&android:layout_above="@id/id_username"&&
&&&&&&&&android:layout_marginBottom="16dp"&&
&&&&&&&&android:src="@mipmap/ic_launcher"/&&&
&/RelativeLayout&&&
& & & &menu的文件就不贴了,更加详细的可以去参考Android 自己实现 NavigationView [Design Support Library(1)]。
& & & &大体看完布局文件以后,有几个点要特别注意:
& & & &o&ToolBar高度设置为wrap_content
& & & &o&ToolBar添加属性android:fitsSystemWindows="true"
& & & &o&header_just_username.xml的跟布局RelativeLayout,添加属性android:fitsSystemWindows="true"
& & & &android:fitsSystemWindows这个属性,主要是通过调整当前设置这个属性的view的padding去为我们的status_bar留下空间。
& & & &根据上面的解释,如果你不写,那么状态栏和Toolbar就会有挤一块的感觉了,类似会这样:
& & & &ok,最后看下代码。
& & & &(三)Activity的代码
package&com.zhy.&&
import&android.os.B&&
import&android.support.v7.app.AppCompatA&&
import&android.support.v7.widget.T&&
public&class&MainActivity&extends&AppCompatActivity&&
&&&&@Override&&
&&&&protected&void&onCreate(Bundle&savedInstanceState)&&
&&&&&&&&super.onCreate(savedInstanceState);&&
&&&&&&&&setContentView(R.layout.activity_main);&&
&&&&&&&&Toolbar&toolbar&=&(Toolbar)&findViewById(R.id.id_toolbar);&&
&&&&&&&&setSupportActionBar(toolbar);&&
&&&&&&&&//pat(this,&getResources().getColor(R.color.status_bar_color));&&
&&&&&&&&//pat(this);&&
& & & &没撒说的,就是setSupportActionBar。
& & & &那么现在4.4的效果图是:
& & & &其实还不错,有个渐变的效果。
& & & &现在5.x的效果:
& & & &可以看到5.x默认并非是一个渐变的效果,类似是一个深一点的颜色。
& & & &再看看我们md的规范
& & & &状态栏应该是一个比Toolbar背景色,稍微深一点的颜色。
& & & &这么看来,我们还是有必要去为4.4做点适配工作,让其竟可能和5.x显示效果一致,或者说尽可能符合md的规范。
& & & &四、调整4.4的显示方案
& & & &那么问题来了?如何做呢?
& & & &咱们这么看,4.4之后加入windowTranslucentStatus的属性之后,也就是我们可以用到状态栏的区域了。
& & & &既然我们可以用到这块区域,那么我们只要在根布局去设置一个与状态栏等高的View,设置背景色为我们期望的颜色就可以了。
& & & &于是有了以下的代码:
package&com.zhy.&&
import&android.annotation.TargetA&&
import&android.app.A&&
import&android.content.C&&
import&android.graphics.C&&
import&android.os.B&&
import&android.view.V&&
import&android.view.ViewG&&
&*&Created&by&zhy&on&15/9/21.&
public&class&StatusBarCompat&&
&&&&private&static&final&int&INVALID_VAL&=&-1;&&
&&&&private&static&final&int&COLOR_DEFAULT&=&Color.parseColor("#");&&
&&&&@TargetApi(Build.VERSION_CODES.LOLLIPOP)&&
&&&&public&static&void&compat(Activity&activity,&int&statusColor)&&
&&&&&&&&if&(Build.VERSION.SDK_INT&&=&Build.VERSION_CODES.LOLLIPOP)&&
&&&&&&&&{&&
&&&&&&&&&&&&if&(statusColor&!=&INVALID_VAL)&&
&&&&&&&&&&&&{&&
&&&&&&&&&&&&&&&&activity.getWindow().setStatusBarColor(statusColor);&&
&&&&&&&&&&&&}&&
&&&&&&&&&&&&&&
&&&&&&&&}&&
&&&&&&&&if&(Build.VERSION.SDK_INT&&=&Build.VERSION_CODES.KITKAT&&&&Build.VERSION.SDK_INT&&&Build.VERSION_CODES.LOLLIPOP)&&
&&&&&&&&{&&
&&&&&&&&&&&&int&color&=&COLOR_DEFAULT;&&
&&&&&&&&&&&&ViewGroup&contentView&=&(ViewGroup)&activity.findViewById(android.R.id.content);&&
&&&&&&&&&&&&if&(statusColor&!=&INVALID_VAL)&&
&&&&&&&&&&&&{&&
&&&&&&&&&&&&&&&&color&=&statusC&&
&&&&&&&&&&&&}&&
&&&&&&&&&&&&View&statusBarView&=&new&View(activity);&&
&&&&&&&&&&&&ViewGroup.LayoutParams&lp&=&new&ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,&&
&&&&&&&&&&&&&&&&&&&&getStatusBarHeight(activity));&&
&&&&&&&&&&&&statusBarView.setBackgroundColor(color);&&
&&&&&&&&&&&&contentView.addView(statusBarView,&lp);&&
&&&&&&&&}&&
&&&&public&static&void&compat(Activity&activity)&&
&&&&&&&&compat(activity,&INVALID_VAL);&&
&&&&public&static&int&getStatusBarHeight(Context&context)&&
&&&&&&&&int&result&=&0;&&
&&&&&&&&int&resourceId&=&context.getResources().getIdentifier("status_bar_height",&"dimen",&"android");&&
&&&&&&&&if&(resourceId&&&0)&&
&&&&&&&&{&&
&&&&&&&&&&&&result&=&context.getResources().getDimensionPixelSize(resourceId);&&
&&&&&&&&}&&
&&&&&&&&return&&&
& & & &代码的思路很简单,根据找到android.R.content,在其中添加一个(高度为statusbarHeight,背景色为我们设置的颜色,默认为半透明的黑色)。
& & & &那么只需要在Activity里面去写上:
pat(this);&&
& & & &就可以了。
& & & &如果你希望自己设置状态看颜色,那么就用这个方法:
pat(this,&getResources().getColor(R.color.status_bar_color));&&
& & & &这样的话我们就解决了4.4到5.x的适配问题,一行代码解决,感觉还是不错的。
& & & &最后提一下,对于5.0由于提供了setStatusBarColor去设置状态栏颜色,但是这个方法不能在主题中设置windowTranslucentStatus属性。所以,可以编写一个value-v21文件夹,里面styles.xml写入:
XML/HTML代码
&resources&&&
&&&&&!--&Base&application&theme.&--&&&
&&&&&style&name="AppTheme"&parent="@style/BaseAppTheme"&&&
&&&&&/style&&&
&/resources&&&
& & & &其实就是不要有windowTranslucentStatus属性。
& & & &接下来,对于默认的效果就不测试了,参考上面的效果图。
& & & &我们测试个设置状态栏颜色的,我们这里设置个红色。
& & & &4.4 模拟器
& & & &5.x 真机
& & & &ok,这样就结束啦~~
《爱加密》Android apk加密保护视频教程剪辑:
&源码地址:
& & & &其实就是不要有windowTranslucentStatus属性。
项目分享:移动商城_微信小程序
源代码下载(百度网盘): &
功能包括:商品橱窗,购物车,结账等功能
这个不错,花了半天看了这些代码,比较规范,很好的学习范例高级会员, 积分 1547, 距离下一级还需 53 积分
主题帖子社区积分
机&&&&&&&型:魅蓝 note2版&&&&&&&本:6.7.5.9 beta总签到数:421
轻松注册,让你轻松玩转Flyme社区
才可以下载或查看,没有帐号?
为什么我调了关闭或者开启都一样,我这种白色的壁纸就看不到时间了
2016纪念勋章2016年度评选纪念
解答解答组[原]Android状态栏微技巧,带你真正理解沉浸式模式 - 推酷
[原]Android状态栏微技巧,带你真正理解沉浸式模式
本文同步发表于我的微信公众号,扫一扫文章底部的二维码或在微信搜索 郭霖 即可关注,每天都有文章更新。
记得之前有朋友在留言里让我写一篇关于沉浸式状态栏的文章,正巧我确实有这个打算,那么本篇就给大家带来一次沉浸式状态栏的微技巧讲解。
其实说到沉浸式状态栏这个名字我也是感到很无奈,真不知道这种叫法是谁先发起的。因为Android官方从来没有给出过沉浸式状态栏这样的命名,只有沉浸式模式(Immersive Mode)这种说法。而有些人在没有完全了解清楚沉浸模式到底是什么东西的情况下,就张冠李戴地认为一些系统提供的状态栏操作就是沉浸式的,并且还起了一个沉浸式状态栏的名字。
比如之前就有一个QQ群友问过我,像饿了么这样的沉浸式状态栏效果该如何实现?
这个效果其实就是让背景图片可以利用系统状态栏的空间,从而能够让背景图和状态栏融为一体。
本篇文章当中我会教大家如何实现这样的效果,但这个真的不叫沉浸式状态栏。因此,这算是一篇技术+普及的文章吧,讲技术的同时也纠正一下大家之前错误的叫法。
什么是沉浸式?
先来分析一下叫错的原因吧,之所以很多人会叫错,是因为根本就不了解沉浸式是什么意思,然后就人云亦云跟着叫了。那么沉浸式到底是什么意思呢?
根据百度百科上的定义,沉浸式就是要给用户提供完全沉浸的体验,使用户有一种置身于虚拟世界之中的感觉。
比如说现在大热的VR就是主打的沉浸式体验。
那么对应到Android操作系统上面,怎样才算是沉浸式体验呢?这个可能在大多数情况下都是用不到的,不过在玩游戏或者看电影的时候就非常重要了。因为游戏或者影视类的应用都希望能让用户完全沉浸在其中,享受它们提供的娱乐内容,但如果这个时候在屏幕的上方还显示一个系统状态栏的话,可能就会让用户分分钟产生跳戏的感觉。
那么我们来看一下比较好的游戏都是怎么实现的,比如说海岛奇兵:
海岛奇兵的这种模式就是典型的沉浸式模式,它的整个屏幕中显示都是游戏的内容,没有状态栏也没有导航栏,用户玩游戏的时候就可以完全沉浸在游戏当中,而不会被一些系统的界面元素所打扰。
然后我们再来看一下爱奇艺的实现:
同样也是类似的,爱奇艺将整个屏幕作为影视的展示区,用户在看电影的时候眼中就只会有电影的内容,这样就不会被其他一些无关的东西所分心。
这才是沉浸式模式的真正含义,而所谓的什么沉浸式状态栏纯粹就是在瞎叫,完全都没搞懂“沉浸式” 这三个字是什么意思。
不过虽然听上去好像是很高大上的沉浸式效果,实际看上去貌似就是将内容全屏化了而已嘛。没错,Android沉浸式模式的本质就是全屏化,不过我们今天的内容并不仅限于此,因为还要实现饿了么那样的状态栏效果。那么下面我们就开始来一步步学习吧。
隐藏状态栏
一个Android应用程序的界面上其实是有很多系统元素的,观察下图:
可以看到,有状态栏、ActionBar、导航栏等。而打造沉浸式模式的用户体验,就是要将这些系统元素全部隐藏,只留下主体内容部分。
比如说我现在新建了一个空项目,然后修改布局文件中的代码,在里面加入一个ImageView,如下所示:
&RelativeLayout
xmlns:android=&/apk/res/android&
android:layout_width=&match_parent&
android:layout_height=&match_parent&&
&ImageView
android:layout_width=&match_parent&
android:layout_height=&match_parent&
android:src=&@drawable/bg&
android:scaleType=&centerCrop& /&
&/RelativeLayout&
这里将ImageView的宽和高都设置成match_parent,让图片充满屏幕。现在运行一下程序,效果如下图所示。
如果你将图片理解成游戏或者电影界面的话,那这个体验离沉浸式就差得太远了,至少状态栏和ActionBar得要隐藏起来了吧?没关系,我们一步步进行优化,并且在优化中学习。
隐藏状态栏和ActionBar的方式在4.1系统之上和4.1系统之下还是不一样的,这里我就不准备考虑4.1系统之下的兼容性了,因为过于老的系统根本就没有提供沉浸式体验的支持。
修改MainActivity中的代码,如下所示:
public class MainActivity extends AppCompatActivity {
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
View decorView = getWindow().getDecorView();
int option = View.SYSTEM_UI_FLAG_FULLSCREEN;
decorView.setSystemUiVisibility(option);
ActionBar actionBar = getSupportActionBar();
actionBar.hide();
这里先调用getWindow().getDecorView()方法获取到了当前界面的DecorView,然后调用它的setSystemUiVisibility()方法来设置系统UI元素的可见性。其中,SYSTEM_UI_FLAG_FULLSCREEN表示全屏的意思,也就是会将状态栏隐藏。另外,根据Android的设计建议,ActionBar是不应该独立于状态栏而单独显示的,因此状态栏如果隐藏了,我们同时也需要调用ActionBar的hide()方法将ActionBar也进行隐藏。
现在重新运行一下程序,效果如下图所示。
这样看上去就有点沉浸式效果的模样了。
虽说这才是正统的沉浸式含义,但有些朋友可能想实现的就是饿了么那样的状态栏效果,而不是直接把整个系统状态栏给隐藏掉,那么又该如何实现呢?
其实也很简单,只需要借助另外一种UI Flag就可以了,如下所示:
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (Build.VERSION.SDK_INT &= 21) {
View decorView = getWindow().getDecorView();
int option = View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
| View.SYSTEM_UI_FLAG_LAYOUT_STABLE;
decorView.setSystemUiVisibility(option);
getWindow().setStatusBarColor(Color.TRANSPARENT);
ActionBar actionBar = getSupportActionBar();
actionBar.hide();
首先需要注意,饿了么这样的效果是只有5.0及以上系统才支持,因此这里先进行了一层if判断,只有系统版本大于或等于5.0的时候才会执行下面的代码。
接下来我们使用了SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN和SYSTEM_UI_FLAG_LAYOUT_STABLE,注意两个Flag必须要结合在一起使用,表示会让应用的主体内容占用系统状态栏的空间,最后再调用Window的setStatusBarColor()方法将状态栏设置成透明色就可以了。
现在重新运行一下代码,效果如下图所示。
可以看到,类似于饿了么的状态栏效果就成功实现了。
再声明一次,这种效果不叫沉浸式状态栏,也完全没有沉浸式状态栏这种说法,我们估且可以把它叫做透明状态栏效果吧。
隐藏导航栏
现在我们已经成功实现隐藏状态栏的效果了,不过屏幕下方的导航栏还比较刺眼,接下来我们就学习一下如何将导航栏也进行隐藏。
其实实现的原理都是一样的,隐藏导航栏也就是使用了不同的UI Flag而已,修改MainActivity中的代码,如下所示:
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
View decorView = getWindow().getDecorView();
int option = View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_FULLSCREEN;
decorView.setSystemUiVisibility(option);
ActionBar actionBar = getSupportActionBar();
actionBar.hide();
这里我们同时使用了SYSTEM_UI_FLAG_HIDE_NAVIGATION和SYSTEM_UI_FLAG_FULLSCREEN,这样就可以将状态栏和导航栏同时隐藏了。现在重新运行一下程序,效果如图所示。
这次看上去好像终于是完全全屏化了,但其实上这离真正的沉浸式模式还差得比较远,因为在这种模式下,我们触摸屏幕的任意位置都会退出全屏。
这显然不是我们想要的效果,因此这种模式的使用场景比较有限。
除了隐藏导航栏之外,我们同样也可以实现和刚才透明状态栏类似的效果,制作一个透明导航栏:
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (Build.VERSION.SDK_INT &= 21) {
View decorView = getWindow().getDecorView();
int option = View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
| View.SYSTEM_UI_FLAG_LAYOUT_STABLE;
decorView.setSystemUiVisibility(option);
getWindow().setNavigationBarColor(Color.TRANSPARENT);
getWindow().setStatusBarColor(Color.TRANSPARENT);
ActionBar actionBar = getSupportActionBar();
actionBar.hide();
这里使用了SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION,表示会让应用的主体内容占用系统导航栏的空间,然后又调用了setNavigationBarColor()方法将导航栏设置成透明色。现在重新运行一下程序,效果如下图所示。
真正的沉浸式模式
虽说沉浸式导航栏这个东西是被很多人误叫的一种称呼,但沉浸式模式的确是存在的。那么我们如何才能实现像海岛奇兵以及爱奇艺那样的沉浸式模式呢?
首先你应该确定自己是否真的需要这个功能,因为除了像游戏或者视频软件这类特殊的应用,大多数的应用程序都是用不到沉浸式模式的。
当你确定要使用沉浸式模式,那么只需要重写Activity的onWindowFocusChanged()方法,然后加入如下逻辑即可:
public class MainActivity extends AppCompatActivity {
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
if (hasFocus && Build.VERSION.SDK_INT &= 19) {
View decorView = getWindow().getDecorView();
decorView.setSystemUiVisibility(
View.SYSTEM_UI_FLAG_LAYOUT_STABLE
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_FULLSCREEN
| View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);
沉浸式模式的UI Flag就这些,也没什么好解释的,如果你需要实现沉浸式模式,直接将上面的代码复制过去就行了。需要注意的是,只有在Android 4.4及以上系统才支持沉浸式模式,因此这里也是加入了if判断。
另外,为了让我们的界面看上去更像是游戏,这里我将MainActivity设置成了横屏模式:
&activity android:name=&.MainActivity&
android:screenOrientation=&landscape&&
&/activity&
这样我们就实现类似于海岛奇兵和爱奇艺的沉浸式模式效果了,如下图所示。
可以看到,界面默认情况下是全屏的,状态栏和导航栏都不会显示。而当我们需要用到状态栏或导航栏时,只需要在屏幕顶部向下拉,或者在屏幕右侧向左拉,状态栏和导航栏就会显示出来,此时界面上任何元素的显示或大小都不会受影响。过一段时间后如果没有任何操作,状态栏和导航栏又会自动隐藏起来,重新回到全屏状态。
这就是最标准的沉浸式模式。
关注我的微信公众号,每天都有优质技术文章推送,你还可以向公众号投稿,将自己总结的技术心得分享给大家。
扫一扫下方二维码或在微信搜索 郭霖 即可关注:
已发表评论数()
请填写推刊名
描述不能大于100个字符!
权限设置: 公开
仅自己可见
正文不准确
标题不准确
排版有问题
主题不准确
没有分页内容
图片无法显示
视频无法显示
与原文不一致Android 系统状态栏沉浸式/透明化完整解决方案 - 简书
Android 系统状态栏沉浸式/透明化完整解决方案
网上已经有很多有关于系统状态栏的解决方案,这篇文章也不会有什么新奇的解决方案,都是本人经过自己试验,统计提炼出来的相对靠谱的一套解决方案.如果是android大牛可以忽略本文,怕让您贱笑.只面向小白,帮助小白减少摸索的时间.
网上有很多争论:
你这状态栏是变色龙状态栏,不是沉浸式的这应该是沉浸式的状态栏吧,系统栏与actionbar颜色设为一致
我只想说去你妹的,老子只要自己的app的状态栏能和主题颜色一致就行了,定义那么多术语,让我等小白情以何堪?吐槽归吐槽,但还是不得不去试着理解下这些术语怎么来的,引用的一段话:
沉浸式全屏模式隐藏status bar(状态栏)使屏幕全屏,让Activity接收所有的(整个屏幕的)触摸事件。
透明化系统状态栏透明化系统状态栏,使得布局侵入系统栏的后面,必须启用属性来调整布局才不至于被系统栏覆盖。
因此,我就这样理解了:
沉浸式不就是隐藏状态栏嘛,状态栏不见了?这不就是app全屏模式嘛?wtf?
而透明式式状态栏就是让app的内容布局可以扩展到系统状态栏?这里有个问题就是为什么能在系统状态栏还显示的情况下,将内容布局扩展到系统状态栏?恩,这应该很好理解,就是Z坐标系的作用了,系统状态栏是覆盖在内容布局上面的,并且是透明的。
貌似这里所谓透明化系统状态栏才是本菜想要的,不管了,现在开始一一试验,至于这概念理解的对不对,管他呢?那到底应该叫什么,那我就叫自适应状态栏,行不行?
让系统状态栏颜色随app主题颜色变化而变化这一设计,毫无疑问,也是向ios学习的:从android4.4开始引进的,并且在5.0进行了改进。因此,也只能将这一特性应用在android4.4以上的手机,无法做到全部适配。记得(貌似是)曾说过:
作为一个android程序员,还能有什么比做出ios风格的app更感到悲哀的呢?哎...
两种情况下的解决方案:
使用toolbar这种方案相对简单,个人喜欢这种方案,本菜虽菜,但喜欢紧跟潮流。toolbar太好用了,
不使用toolbar
1. 使用toolbar的解决方案
这个方法参照了这里,
其基本原理就是:theme里添加style: &item name="android:windowTranslucentStatus"& true &/item&后,包含toolbar的内容布局就可以扩展至系统状态栏,状态栏会覆盖在toolbar上,如果此时使用android:fitsSystemWindows="true",就可以调整内容布局(估计也是在根布局上加padding)恢复到原来位置.但是,上面的解决方案确是给toolbar加上一个padding-top="25dp",这样就可以做到系统状态栏的颜色和toolbar的颜色保持一致.具体方案可以参照上面的薄荷app的方案链接.
简述下步骤(只是简述,有疑问请参照上面薄荷app的链接即可):
引入v7包,并在布局里添加toolbarcompile ‘com.android.support:appcompat-v7:22.2.1’
在代码中设置透明化:if (Build.VERSION.SDK_INT &= Build.VERSION_CODES.KITKAT) {
WindowManager.LayoutParams localLayoutParams = getWindow().getAttributes();
local LayoutParams.flags = (WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS | localLayoutParams.flags);
当然也可以在theme的样式文件里添加style:&item name="android:windowTranslucentStatus"&true&/item&,效果相同,但是大神们都说样式文件里设置在某些型号里不生效.ok,大家都在代码里设置就好了
给toolbar加上padding-top,toolbar代码如下&android.support.v7.widget.Toolbar android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="@dimen/toolbar_padding_top"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
android:background="#30469b"&
&TextView android:layout_gravity="center"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="20sp"
android:text="@string/app_name"/&
&/android.support.v7.widget.Toolbar&
4.其中android:paddingTop="@dimen/toolbar_padding_top"要在values中的styles文件里设为0dp,在values-v19的styles里设为25dp,原因不多说了
这样就可以达成了我们的目标,如果只是这样也就罢了,按照上面做就可以了,关键是本菜是喜欢紧跟潮流的,使用MD风格的DrawerLayout+NavigationView时,在android4.4的手机下,就会变这样了:
android4.4上的效果
很明显,drawerlayout并没用被扩展至系统状态栏,但在android5.0以上效果还是可以的,这让我很奇怪,只能归咎于5.0的优化了
android5.0上的效果
经过各种折腾终于想起来,可以把fitsSystemWindows的特性用在drawerlayout上试试,最后发现居然可以,最终将设置windowTranslucentStatus的代码调整如下:
if (Build.VERSION.SDK_INT &= Build.VERSION_CODES.KITKAT) {
WindowManager.LayoutParams localLayoutParams = getWindow().getAttributes();
local LayoutParams.flags = (WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS | localLayoutParams.flags);
if(Build.VERSION.SDK_INT & Build.VERSION_CODES.LOLLIPOP){
//将侧边栏顶部延伸至status bar
mDrawerLayout.setFitsSystemWindows(true);
//将主页面顶部延伸至虽默认为false,但经测试,DrawerLayout需显示设置
mDrawerLayout.setClipToPadding(false);
最终android4.4上也可以显示正常:
android4.4上修正后的效果
2. 不使用toolbar的解决方案
不使用toolbar时,而是actionbar时,因为actionbar不好定制,所以无法采用上面那个方法,只能采用其它方法,这里的方案主要参考这里:这篇简书看的本菜晕乎乎的,仔细看下来,其实都是基于一个原理:不管有没有actionbar,内容布局的背景颜色一律设为主题颜色,然后有actionbar的话,就将actionbar与内容布局的背景颜色同时设为主题颜色,然后,每个内容布局的根布局都要设上fitsSystemWindows="true"进行调整,感觉超麻烦有没有?
不说多少,简述步骤:
在代码中设置透明化,步骤同上
设置内容布局的根布局的背景颜色为主题颜色,同时设置fitsSystemWindows="true"&LinearLayout xmlns:android="/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/colorPrimary"
android:fitsSystemWindows="true"
android:orientation="vertical"&
在内容布局的下面再设置一层内容布局,设背景颜色为白色(或其它颜色):&LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/c_light_white"
android:gravity="center"
android:orientation="vertical"&
至此,这种方案也完成了,看下效果:
android4.4上的效果
可以看出,这种方案一般情况下,还是可行的,但是有三个问题:
如果用上drawerlayout+navigationview,actionbar就会覆盖在侧边栏上(如上图),暂时未找到解决方案,但是我想说你都用drawerlayout+navigationview了,为何不用toolbar,因此这个问题应该不是问题,况且还可以使用其它的侧边栏实现方式,各位道友可以试试
这种方案在每个根布局上都要设fitsSystemWindows="true"进行调整,当然也有优化方案,可仍然觉得很麻烦,
每个根布局里都要多加的一层布局来覆盖根布局的背景主题颜色
因此,这种方案的确不是上上之选.
本文主要在考虑使用标题栏(actionbar/toolbar)的情况下,做出的方案,当然你也可以自定义标题栏,或者不使用标题栏;其实都可以基于上面一样的道理:
在状态栏透明化的前提下,调整顶部view的padding-top,来达到状态栏自适应一体化的目的
网上还有其它蛮多的解决方案,如:
使用开源库,这个库也挺不错的,可以动态改变系统状态栏颜色,但是作者已经2年没有维护了,现在技术更新迭代这么快,鬼知道这个库会不会出现什么问题,因此可以放弃使用了
如果不怕麻烦,还可以new一个高度和状态栏一样高的view,插入到内容布局的上面,但是,想想都觉得麻烦,我也懒得试了
关于本文中的样例代码已上传至,欢迎star,有问题也欢迎各位撸友,道友们来指正.

我要回帖

更多关于 沉浸式状态栏 的文章

 

随机推荐