互联网科技

Android沉浸式(透明)状态栏适配

作者:金沙国际官网    发布时间:2020-03-13 15:22     浏览次数 :137

[返回]

在Android系统4.4原先,状态栏的背景观和字体颜色都以不能够改换的。然则4.4之后Google增加了改造状态栏背景透明的点子,能够透过三种艺术来设置。直接在Activity中设置Window属性:

先是,作者要促成的末尾效果是那样的,即在Android4.4及以上版本系统上,统一突显为如下效果:

出处: http://blog.csdn.net/lmj623565791/article/details/48649563; 本文出自:【张鸿洋的博客】

@Overrideprotected void onCreate(Bundle savedInstanceState) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS); } super.onCreate(savedInstanceState);}

图片 1

一、概述
方今当心到QQ新版使用了沉浸式状态栏,ok,先声明一下:本篇博客效果下图:

在xml的style文件中安装:

末段效果

图片 2

<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar"> <item name="android:windowTranslucentStatus">true</item></style>

所谓“沉浸式”状态栏

此地所说的沉浸式状态栏,就是指上面包车型大巴效应,状态栏和Toolbar的水彩保持一致,融合为一的效果与利益。

关于那一个状态栏变色到底叫「Immersive Mode」/「Translucent Bars」有意思味能够去 干什么在境内会有无数客户把 「透明栏」(Translucent Bars)称作 「沉浸式顶栏」?地点明白掌握,请勿指导作者说的博文标题起得分外,thx。
恩,接下去正题。
第壹独有领先等于4.4本子帮助那几个半晶莹剔透状态栏的机能,可是4.4和5.0的展现效果有早晚的差异,全数本篇博文内容为:
怎么着贯彻半晶莹剔透状态栏效用在过量4.4本子之上。
怎么着让4.4的服从与5.0的遵循尽恐怕一致。

使用android:windowTranslucentStatus性格须求在res目录下新建values-v19文件夹,style文本要放在在那之中。尽量使用第一种方法类完成,听说是第二种办法在一些小米手提式有线电电话机上未曾效率。

本子差别及缓和办法

正文所用的演示使用的style风格是NoActionBar的,标题栏使用的是Toolbar控件,请知悉。

看了众多参阅小说,都介绍到这些库,大家能够通晓:SystemBarTint。
不过本篇博文并未基于此库,自个儿想了个hack,对于此库源码有空再看了。
二、效果图
先贴下效果图,以便和完毕进度中做下相比
4.4 模拟器

三种方法都以让景况背景栏透明。不过在实际测量试验后意识,在android4.4系统上状态栏的背景是渐变半晶莹剔透。而在android5.0+的种类上又有所区别又有间隔:

Android4.4

Android4.4在先的版本,状态栏的水彩都以玫瑰紫红的,何况不可能改过;但貌似应用软件的Toolbar都不会安装为紫藤色,于是,两者
有不行令人注指标颜料区分,各自占用差异的区域,填充不一致的颜色。简单的讲,Android4.4在先的本子是爱莫能助成功
沉浸式的意义的(做系统开垦的除此之外),所以只要想要统一风格的话,能够设置应用程式最小扶植的版本为4.4,要是
非凡,就不能了,只可以4.4原先贰个体制,4.4及今后贰个体制。

Android4.4起头,新扩张了设置情状栏背景象透明的脾气,新扩展的属性是那八个:

WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS 
WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION

那七个特性分别安装状态栏和导航栏背景观为全透明。(这里只谈谈状态栏,只设置方面叁脾气质就能够,导航栏的好像)
贯彻方式很简短,在Activity伊始化时,调用以下代码:

// Translucent status bar
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
    Window window = getWindow();
    window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
}

是因为是代码设置,所以不能通过xml预览到想要的结果,必必要在4.4真机上运营本事见到成效。

到这里大概存在多少个难题:

1. Toolbar把状态栏的空间占用了,挤到一起。

2. 状态栏和Toolbar并没有完全融为一体,而是从上到下,由黑色渐变到Toolbar的颜色。

首先个场景是必现的,消除方法是在Toolbar的布局文件里丰硕三脾天性:

android:fitsSystemWindows="true"

其一特性必得加在Toolbar也许Toolbar的父控件上,也便是,要是Toolbar直接写在Activity的构造文件里,则在Toolbar上
加那几个天性,倘若Toolbar是include到Activity的布局文件里,则足以加到Toolbar的父控件里;

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context="com.chengsy.immersive.MainActivity">

    <android.support.v7.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@color/colorPrimary"
        android:fitsSystemWindows="true"
        app:title="@string/app_name"
        app:titleTextColor="#FFFFFF">

    </android.support.v7.widget.Toolbar>

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:text="Hello World!" />

</LinearLayout>

地方这种情状,假若写到linearlayout中,就能并发难点,StatusBar的背景象跟任何窗口的背景观相仿(恐怕跟桌面颜色相仿),并不是和Toolbar的
水彩同样。效果如下:

图片 3

质量设置错误效果

其次个场景依据区别的系统厂家,效果不等同,也便是莫衷一是的无绳电话机厂商做的分裂等,不能够,可是否太影响沉浸式的法力。
职能如下:

图片 4

渐变的StatusBar

小结一下,4.4版本,需要安装两个地点来兑现沉浸式效果:

  1. 设置情状栏透明
  2. 设置Toolbar的fitsSystemWindows属性为true

图片 5

在Genymotion模拟器、HTC、nexus6p的android5.0+系统上是半晶莹剔透。在xiaomi、oppo、huawei、leshi等5.0+系统是全透明的。

Android5.0

先看看通过地方的装置,程序运转在Android5.0的装备上是什么样信守:
大概的职能也会有多少个,三个是大家想要的功用,沉浸式,不再配图了,另三个是这么的:

图片 6

在Android5.0某个机器上的效劳

这种效果与利益是状态栏的水彩上边覆盖了一层半晶莹剔透的颜料,不是全透明。当然,原因你知道,差别厂家系统设计员的idea是不均等的,
唯独这里说一下,Google官方的Mertial Design的设计标准是如上海体育场所所示,并非沉浸式的职能,但国内的APP未来广泛比较
喜好沉浸式的效劳。

那正是说只要要联合5.0的效应跟4.4的效益保持一致,全是沉浸式该如何是好???
这么办---
先是,Android5.0起来,系统又新添了安装景况栏颜色值的性质和接口:

WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS

因此这些性格来安装设置状态栏的背景象,来完毕双方融为一炉的作用,代码完结如下:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
        getWindow().addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
        getWindow().clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
        getWindow().setStatusBarColor(Color.TRANSPARENT);// SDK21
}

规律特不难,首先要清空以前设置的FLAG_TRANSLUCENT_STATUS属性,然后增加改正情形栏背景象的性格FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS
,最终给状态栏设置为全透明。

此地有坑,有的5.x的道具,即使调用那句代码
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
气象栏会变象牙白,那个时候必要去掉那句。不过去掉那句代码,在6.0+系统上半透明的状态栏又出现了。所以拍卖办法是判断要是是某种特殊的系统,
不调用上述代码。

5.x 真机

图片 7android4.4图片 8模拟器android5.0+图片 9Samsung5android6.0从效果图也能够看见,下边二种方法使得内容区域延伸到状态栏下边去了。大家能够加多android:fitsSystemWindows来幸免这样的图景。在Activity的根布局文件中加多

Android6.0

对此Android6.0及随后的系统,对那上头的援救就曾经很圆满和集结了,通过4.4设置的FLAG_TRANSLUCENT_STATUS属性和
fitsSystemWindows属性就足以达标想要的机能了,没有供给做非常管理,版本内有的时候不设有机型之间的反差。

只是6.0亦非一心没新的事物(指的是气象栏这一块内容),6.0新增加了设置情形栏里内容色调的习性和接口,通过设置如下属性,能够把状态栏的文字
颜色由亮色改为暗色,亮色是土红,暗色是深红:

getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);

看名字感到跟自家的描素不相像啊,其实,这么些天性是把状态栏标识为亮色调,进而,系统会自行把状态栏的文字内容变为
暗色调,借令你的APP的Toolbar颜色是亮色的,再配上亮色的开始和结果就能够不了然,上边的代码能够消除那一个主题素材,自动将
状态栏的内容改为暗色调。

图片 10

android:fitsSystemWindows="true"

任何难题

  1. 输入框的宽容难点

    若果想要页面尾部的输入框能够被键盘顶起来,何况不影响页面包车型客车沉浸式效果,供给做两点:

     - AndroidManifest.xml文件配置键盘属性:android:windowSoftInputMode="adjustResize"
     - Activity页面根布局设置 android:fitsSystemWindows="true" 属性
    

    构造代码如下:

     <?xml version="1.0" encoding="utf-8"?>
     <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
         xmlns:app="http://schemas.android.com/apk/res-auto"
         xmlns:tools="http://schemas.android.com/tools"
         android:layout_width="match_parent"
         android:layout_height="match_parent"
         android:fitsSystemWindows="true"
         android:orientation="vertical"
         tools:context="com.chengsy.immersive.MainActivity">
    
         <android.support.v7.widget.Toolbar
             android:id="@+id/toolbar"
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
             android:background="@color/colorPrimary"
             android:fitsSystemWindows="true"
             app:title="@string/app_name"
             app:titleTextColor="#FFFFFF">
    
         </android.support.v7.widget.Toolbar>
    
         <LinearLayout
             android:layout_width="match_parent"
             android:layout_height="match_parent"
             android:layout_below="@+id/toolbar"
             android:gravity="bottom">
    
             <EditText
                 android:layout_width="match_parent"
                 android:layout_height="wrap_content"
                 android:text="Hello World!" />
         </LinearLayout>
    
     </RelativeLayout>
    

    因而地点的管理,状态栏的颜料不对了,形成了反动可能桌面的背景观,难题又来了。化解办法的原理就是给状态栏填充上颜色,
    可是,给状态栏改正颜色的属性和接口在5.0才面世,[4.4--5.0State of Qatar版本的如何做?用SystemBarTintManager,Github上的开源库,
    杀鸡取蛋眼下的标题。使用很简短,引用那几个库:

     compile 'com.readystatesoftware.systembartint:systembartint:1.0.3'
    

    代码中装置:

     private SystemBarTintManager tintManager;
    
     tintManager = new SystemBarTintManager(this);
     tintManager.setStatusBarTintColor(getResources().getColor(R.color.colorPrimary));
     tintManager.setStatusBarTintEnabled(true);
    
  2. 其余第三方控件的相配,如ActionMode等

    有用到这些的仁慈去查、去尝尝吧,这几个控件好久不用了,也不知底怎么作用,能够参见那篇小说里的解决办法:
    沉浸式状态栏实现及碰着的坑

  3. 系统厂商的相称,如MIUI系统等

    这里也介绍了MIUI系统的适配难题,供仿效:
    沉浸式状态栏达成及境遇的坑

[new]贴个要是最上部是图形的作用图,其实是一律的,为了便利自身就放侧栏的最上部了。

要么在宗旨style文件中加多

总结

是因为Android系统的开放性,以至系统厂家的不归总,招致Android系统的适配成为了另技师脑仁疼的一大标题,沉浸式的意义同样
倒霉做到一心统雷同式,只可以不遗余力之。通过上面的操作,基本得以确定保障大许多机型和类其他沉浸式效果,但依旧有分别不能适配的
系统或机型,这里也无从一一列举全数的情事,必要程序猿们有指向的设计代码,消除难点。

此地给出本人计算的一个方法,能够在BaseActivity中调用:

率先,Toolbar要安装fitsSystemWindows属性,假若页面蕴涵EditText,需同不常间在页面根构造增添fitsSystemWindows属性;
援助,援引SystemBarTintManager库提供扶持;
终极,调用如下代码:

private SystemBarTintManager tintManager;
protected void initWindow() {
    // 4.4及以上版本设置状态栏透明
    Window window = getWindow();
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
        // Translucent status bar
        window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
    }

    // 解决4.4-5.0版本之间,页面包含EditText无法适配的问题
    {
        // create our manager instance after the content view is set
        mTintManager = new SystemBarTintManager(this);
        // enable status bar tint
        mTintManager.setStatusBarTintEnabled(true);
        // enable navigation bar tint
        mTintManager.setNavigationBarTintEnabled(true);

        // 自定义状态栏的颜色
        mTintManager.setStatusBarTintColor(getResources().getColor(R.color.colorPrimary));
    }

    // 解决[5.0-5.1.1]版本状态栏没有全透明的系统适配问题
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
        // 解决部分5.x系统使用状态栏透明属性后状态栏变黑色,不使用这句代码,在6.0设备上又出现半透明状态栏
        // 需要特殊处理
        window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);

        window.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
                | View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
        window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
        window.setStatusBarColor(Color.TRANSPARENT);
    }

    // 把状态栏标记为浅色,然后状态栏的字体颜色自动转换为深色。
    // if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
    //     getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
    // }
}

图片 11

<item name="android:fitsSystemWindows">true</item>

稍等,csdn图片服务器格外…
ok,有了效用图之后就起来看贯彻了。
三、完结半透明状态栏
因为本例使用了NavigationView,所以布局代码稍多,当然假如你无需,能够慈悲开展筛减。
注意引进相关信赖:

图片 12android4.4图片 13模拟器android5.0+图片 14索爱5android6.0上海教室为了方便观看状态栏的背景颜色,就将Activity的布局文件的背景观设置成了丁亥革命。能够见见Toolbar所在的内容区域并未有冲凉到状态栏下边了,而且状态栏的背景颜色照旧在此之前同样,只是将内容区域向下偏移了状态栏高度的偏离。那是因为fitsSystemWindows属性使得构造的paddingTop被重复改写了(paddingTop追加了状态栏的莫斯中国科学技术大学学)。要贯彻沉浸式的状态栏,其实正是状态栏的背景颜色和Toolbar的水彩相仿。那么大家将Activity的背景观改为Toolbar猩红(内容区域的背景颜色设置为铁青)看下效果:图片 15android4.4图片 16模拟器android5.0+图片 17HUAWEI5android6.0除了通过fitsSystemWindows其一天性,我们得以团结给在Toolbar的上边增多一个和景况栏中度一致的Veiw,并将以此View的背景观设置成和Toolbar的背景象同样。也足以直接给Toobar设置paddingTop极其状态栏中度值。为了方便,笔者日常是行使重写Toolbar,改写它的paddingTop值来达成。

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'
/** * Created by xiaoyanger on 2017/3/1. * 沉浸式、版本兼容的Toolbar,状态栏透明. */public class CompatToolbar extends Toolbar { public CompatToolbar(Context context) { this(context, null); } public CompatToolbar(Context context, AttributeSet attrs) { this(context, attrs, 0); } public CompatToolbar(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); setup(); } public void setup() { int compatPadingTop = 0; // android 4.4以上将Toolbar添加状态栏高度的上边距,沉浸到状态栏下方 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { compatPadingTop = getStatusBarHeight(); } this.setPadding(getPaddingLeft(), getPaddingTop() + compatPadingTop, getPaddingRight(), getPaddingBottom; } public int getStatusBarHeight() { int statusBarHeight = 0; int resourceId = getResources().getIdentifier("status_bar_height", "dimen", "android"); if (resourceId > 0) { statusBarHeight = getResources().getDimensionPixelSize(resourceId); } Log.d("CompatToolbar", "状态栏高度:" + px2dp(statusBarHeight) + "dp"); return statusBarHeight; } public float px2dp(float pxVal) { final float scale = getContext().getResources().getDisplayMetrics().density; return (pxVal / scale); }}

(一)colors.xml 和 styles.xml
第一大家定义多少个颜色:
res/values/color.xml

亟待在意的是,英特网有过多文章说状态栏的冲天是25dp,但实际上测量试验后开采实际不是装有的机型都以25dp。使用getStatusBarHeight()能够精确的收获状态栏的万丈值,看下获取到惊人的日记:

<?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>

图片 18android4.4模拟器图片 19android6.0模拟器图片 20oppo r9图片 21BlackBerry5挨门逐户机型得到到的气象栏中度超多都不平等,所以最佳大概重写Toolbar,动态获取到系统状态栏的高度来改写它的上面距。

上边定义多少个styles.xml
瞩目文件夹的路径:
values/styles.xml

进口的大多数手提式有线电话机在android5.0+的系统都将原生的半透明状态栏改成了全透明,由此通过地方的方法为主到达了沉浸式体验。其实在原生android5.0+系统上得以经过这些措施使事态栏背景象完全透明:

<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>