Android沉浸式状态栏(透明状态栏)最佳实现
Android沉浸式状态栏(透明状态栏)最佳实现
在Android4.4之前,我们的应用没法改变手机的状态栏颜色,当我们打开应用时,会出现上图中左侧的画面,在屏幕的顶部有一条黑色的状态栏,和应用的风格非常不协调;为了提供更好的界面交互,google在Android4.4以后提供了设置沉浸式状态栏的方法,对于沉浸式状态栏这个名字存在争议,我们不做讨论,实际的效果其实就是透明的状态栏,然后在状态栏的位置显示我们自定义的颜色,通常为应用的actionbar的颜色,或者是将应用的整体的一张图片也占据到状态栏中,如下图所示:
由于这种透明的状态栏是在Android4.4以后才出现的,所以我们需要为4.4以上的版本做适配,方法有两种,一种是在资源文件(style)中设置,一个是在代码中设置。
在资源文件中设置透明状态栏
首先,我们先在values下的style中加入如下代码:
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item>
</style>
<style name="AppTheme.Main" parent="AppTheme" />
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
AppTheme.Main是我们要设置给activity的主题,它应该继承于AppTheme.NoActionBar,然后
我们在values-v19中加入同样的AppTheme.Main,如下所示:
<style name="AppTheme.Main" parent="AppTheme.NoActionBar">
<item name="android:windowTranslucentStatus">true</item>
</style>
- 1
- 2
- 3
然后运行程序,效果如图所示:
图片中我们发现,虽然我们实现了透明的状态栏,但是上边的文字和状态栏的信息重叠了。为了修复这个问题,我们应该在布局文件的根布局中加入android:fitsSystemWindows=”true” 就可以了,加入后效果如下:
应用的文字和系统显示的文字错开了,这也是我们最终的显示效果
需要注意的几点:
- 为Android4.4+适配的同时,不要忘了在values的style.xml中加入同名的自定义style,不然4.4以下会报错
- 不要忘记在布局文件中加入 android:fitsSystemWindows=”true”,不然布局内容会和状态栏内容重叠
在Android5.0中,透明标题的效果和4.4中有所不同,但是实现方法相同,我们可以不必为5.0+单独适配,同时5.0+的版本提供了新的API
android:statusBarColor,可以用来单独设置状态栏的颜色,但是这种方法不适用于我们例子中的图片占据状态栏,它适用于纯色的状态栏,并且它应该放到value-v21文件夹中
上边的例子中,我们只设置了一个图片,使其占据了状态栏。但是我们平常见到更多的可能不是这种,而且带actionbar的情况,如下所示:
在上图中,存在一个actionbar,然后状态栏的颜色与其相同,接下来我们来实现这种效果。
style文件不用改变,我们需要在布局文件中加入一个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:background="@color/colorAccent"
android:orientation="vertical"
tools:context="com.zephyr.musicapp.MainActivity">
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fitsSystemWindows="true"
android:background="?attr/colorPrimary"
app:popupTheme="@style/AppTheme.PopupOverlay"/>
</LinearLayout>
然后在activity中
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
在一个LinearLayout中包含了一个toolbar,和第一个例子相比,我们把android:fitsSystemWindows=”true”加在了Toolbar上边,而不是LinearLayout中,如果把android:fitsSystemWindows=”true”放到LinearLayout中,会出现下边的效果:
虽然状态栏透明了,但是颜色却和根布局的颜色相同而不是toolbar,这样显然不行,如果我们把android:fitsSystemWindows=”true”放到toolbar中就可以实现我们的效果,如下图所示:
在这里,我们还需要特别注意一个地方,那就是在设置toolbar高度的时候,应该设置成wrap_content,不然也没法实现我们的效果,比如我把高度固定为50dp,效果如下:
虽然占据了状态栏,但是toolbar的高度明显不够了,效果很不好。
在Android5.0以后,增加了新的API android:statusBarColor
用于设置状态栏的颜色,同时以前的windowTranslucentStatus也是对它有效的,所以如果想通过新的API设置状态栏颜色的话,首先应该将windowTranslucentStatus设置为false,不然是没有效果的。
以上就是通过资源文件设置透明状态栏的方法。
代码中设置透明状态栏
在代码中设置透明状态栏的方法也很简单,思路就是首先通过
WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS设置当前window为透明状态栏,这样标题栏就可以占据状态栏了,但是会出现布局中的内容和状态栏的内容重叠的问题,为了解决这个问题,我们应该获得状态栏的高度,然后设置标题栏的paddingTop为状态栏的高度,这样就可以实现透明效果的标题栏的,代码如下:
protected void setImmerseLayout(View view) {// view为标题栏
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
Window window = getWindow();
window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
int statusBarHeight = getStatusBarHeight(this.getBaseContext());
view.setPadding(0, statusBarHeight, 0, 0);
}
}
public 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 result;
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
fitSystemWindows属性:
官方描述:
Boolean internal attribute to adjust view layout based on system windows
such as the status bar. If true, adjusts the padding of this view to
leave space for the system windows. Will only take effect if this view
is in a non-embedded activity.
补充:
当为纯色actionbar的情况下,我们将toolbar的高度设为wrap_content,并且将fitsSystemWindows=“true”参数设置到了toolbar上,这样虽然实现了4.4版本的沉浸效果,但是却不能有效的适配5.0及以上的版本,所以做出以上修改。
在4.4版本上:
1. 我们将根布局的背景颜色设置成和toolbar一样的,并且设fitsSystemWindows为true。
2. toolbar的fitsSystemWindows属性去掉,并且高度设置为?attr/actionBarSize
3. 在toolbar下增加一个子布局,颜色设置为white,这样就可以在4.4及5.0以上实现带actionbar的沉浸式布局
2017.12.14更新:
使用纯色actionbar的时候,可以使用容器包裹toolbar,只设置容器
fitsSystemWindows为true。由于fitsSystemWindows属性本质上是给当前控件设置了一个padding,所以我们设置到根布局的话,会导致状态栏是透明的,并且和窗口背景一样,和toolbar背景不同。如果我们设置给toolbar,则会由于padding的存在,导致toolbar的内容下移。所以我们选择使用LinearLayout包裹toolbar,并将toolbar的背景等属性设置在appbarlayout上就可以完美实现效果,代码:
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/colorPrimary"
android:fitsSystemWindows="true"
android:orientation="vertical">
<android.support.v7.widget.Toolbar
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:title="Login"/>
</LinearLayout>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
Android沉浸式状态栏(透明状态栏)最佳实现的更多相关文章
- Android沉浸式(侵入式)标题栏(状态栏)Status(三)
Android沉浸式(侵入式)标题栏(状态栏)Status(三) 从附录文章1,2可以看到,依靠Android系统提供的标准方案,状态栏即便在透明状态下,仍然有些半透明而不是全透明.本文是And ...
- android 沉浸式状态栏的实现
本文介绍一种简单的实现沉浸式状态栏的方法,要高于或等于api19才可以. 实现android沉浸式状态栏很简单,添加代码两步就可以搞定. 一.在activity中添加 getWindow().addF ...
- [置顶]
Xamarin android沉浸式状态栏
虽然关于android "沉浸式"状态栏有很多博客介绍过,从小菜到大神无一例外.我第一次看到这种"沉浸"式的效果我也以为真的是这么叫,然而根本不是这么回事,完全 ...
- Android 沉浸式状态栏完美解决方案
现在搜索Android 沉浸式状态栏,真的是一堆一堆,写的特别多,但是真正用的舒服的真没有,在这里自己整理一下开发记录 注意,在使用这个步骤过程之前,请把之前设置的代码注释一下 把布局带有androi ...
- 【Android实战】Android沉浸式状态栏实现(下)
之前的Android沉浸式状态栏实现并没有考虑软键盘的影响,接下来的内容将会针对这个问题给出解决方式,先看一下效果图 这个是一个留言板的效果图: 即弹出软键盘的时候并不会导致整个布局上移. 详细怎样实 ...
- Android 沉浸式状态栏 实现方式二 ( 更简单 )
以前写过一个沉浸式状态栏 的实现方式 Android 沉浸式状态栏 实现方式一 现在有个更为简单的实现方式 . 相关链接 http://www.apkbus.com/forum.php?mod=vie ...
- Android沉浸式(侵入式)标题栏(状态栏)Status(二)
Android沉浸式(侵入式)标题栏(状态栏)Status(二) 附录1以xml写style实现了Android沉浸式(侵入式)状态栏(标题栏),同样以上层Java代码实现.在附录文章1的基础上 ...
- Android沉浸式(侵入式)标题栏(状态栏)Status(一)
Android沉浸式(侵入式)标题栏(状态栏)Status(一) 现在越来越多的APP设计采用这种称之为沉浸式状态栏(Status)的设计,这种沉浸式状态栏又称之"侵入式"状 ...
- flutter android沉浸式状态栏
import 'package:flutter/services.dart'; import 'dart:io'; class _MyAppState extends State<MyApp&g ...
随机推荐
- JavaScript 的类型
var a ="111"; console.log(a.constructor);//function String() { [native code]} var b= Strin ...
- hust训练赛20160330--B - 又见LKity
Problem 2122 又见LKity Time Limit: 1000 mSec Memory Limit : 32768 KB Problem Description 嗨!大家好,在Templ ...
- 在oracle下我们如何正确的执行数据库恢复
标签:oracle 数据库 恢复 原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://jiujian.blog.51cto.com/4 ...
- Gym - 100548C The Problem Needs 3D Arrays (最大密度子图)
TK在大多数 Unix平台.Windows平台和Macintosh系统都是预装好的,TKinter 模块是 Tk GUI 套件的标准Python接口.可实现Python的GUI编程. Tkinter模 ...
- [luoguP1627] 中位数(模拟?)
传送门 水题,怎么评到这个难度的? #include <cstdio> #include <iostream> #define N 200001 int n, b, p, an ...
- msp430入门编程21
msp430中C语言的扩展--#pragma编译命令
- poj2186 求有向图G中所有点都能到达的点的数量
/*题意:有向图,求这样的点的数量:所有点都能到达它.缩点成有向无环图,思:如果该强连通有出度,那么 从该出度出去的边必然回不来(已经缩点了),所以有出度的强连通必然不是.那么是不是所有出度为0的强连 ...
- Java 基础部分知识复习
面向对象的特征: 继承.封装和多态 封装 : 把客观事物封装成抽象的类,并且类可以把自己的数据和方法只让可信的类或者对象去操作.对不可信的信息进行隐藏. 继承: 它可以使用现有类的功能,并在无需重新编 ...
- 基于数据库的代码自动生成工具,生成JavaBean、生成数据库文档、生成前后端代码等(v6.0.0版)
TableGo v6.0.0 版震撼发布,此次版本更新如下: 1.UI界面大改版,组件大调整,提升界面功能的可扩展性. 2.新增BeautyEye主题,界面更加清新美观,也可以通过配置切换到原生Jav ...
- JAVA实现选择排序,插入排序,冒泡排序,以及两个有序数组的合并
一直到大四才开始写自己的第一篇博客,说来实在有点羞愧.今天写了关于排序的算法题,有插入排序,冒泡排序,选择排序,以下贴上用JAVA实现的代码: public class test5 { public ...