概述 首先我们得了解什么是透明状态栏以及什么是沉浸式状态栏,以及其区别,国内习惯称变色状态栏为沉浸式状态栏,但是两者是有本质区别的:
沉浸式: Android 4.4中,沉浸式体验得到了再次强化,提供了一种“全屏模式”(Full-screen Immersive Mode)。全屏模式又分两种,一种叫后撤式 (Lean Back),另一种叫做沉浸式(Immersive)。后撤式已经在之前的系统中被广泛使用了——当你在优酷APP中观看视频时,大部分时间手指是不会去碰屏幕的。这种情况下,虚拟键和状态栏都会自动隐藏,但当你触摸屏幕的时候,它们又会出现。而新加入的沉浸式则不太一样,在沉浸式全屏状态下,对屏幕的操作并不会唤出系统栏。想要唤出系统栏,你必须从屏幕的上/下边缘向屏幕内划入。沉浸式的全屏状态更适合游戏和阅读这样的应用。
变色:
透明: Android 4.4 一个很重要的改变就是透明系统栏.。新的系统栏是渐变透明的, 可以最大限度的允许屏幕显示更多内容, 也可以让系统栏和 Action Bar 融为一体, 仅仅留下最低限度的背景保护以免通知通知栏内容和 Action Bar 文字/图标难以识别。谷歌把这种效果称之为:Translucent Bar。 Translucent Bar 是 Android 对 Edge to Edge 尝试中的一个, 也是最容易被用户注意到的. 它的初始目的就是要最大化可视面积和淡化系统界面的存在感。
变色: Android 5.0后可以自由设置状态栏颜色,所以也可以称作变色状态栏。
所以我们这里讲的是变色状态栏,变色状态栏就是如何对 StatusBar(状态栏)的背景透明操作;当我们打开应用时,一般如果不对状态栏进行修改的话,在屏幕的顶部有一条默认的(黑色、灰色、其他)状态栏,和应用的风格非常不协调,为了提供更好的界面交互,然后在状态栏的位置显示我们自定义的颜色,通常为应用的TitleBar的颜色,或者是将应用的整体的一张图片也占据到状态栏中,这个时候我们就需要对状态栏的背景进行操作。状态栏详解点击
StatusBar、TitleBar StatusBar是状态栏,它处于屏幕的最顶部,正常情况下它是显示的,它和TitleBar之间没有直接的关系;
TitleBar是标题栏,比如ActionBar、ToolBar,紧位于状态栏的下方显示。
ActionBar(操作栏) 是在Android 3.0(API 11)中加入到SK中的。
ToolBar(工具栏)是 Android 5.0 推出的一个 Material Design 风格的导航控件 ,用来取代之前的 Actionbar 。与 Actionbar 相比,Toolbar 明显要灵活的多。它不像 Actionbar 一样,一定要固定在Activity的顶部,而是可以放到界面的任意位置。与ActionBar相比显示效果跟ActionBar并没有区别。但优点是自定义视图的操作更加简单:
1.设置导航栏图标;
2.设置App的logo;
3.支持设置标题和子标题;
4.支持添加一个或多个的自定义控件;
5.支持Action Menu;
ActionBar 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 <style name="AppCompatActivity_ActionBarTheme" parent="Theme.AppCompat.Light.DarkActionBar"> <!-- Customize your theme here. --> <item name="colorPrimary">@color/colorPrimary</item> <item name="colorPrimaryDark">@color/colorPrimaryDark</item> <item name="colorAccent">@color/colorAccent</item> </style> @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); ActionBar actionBar = getSupportActionBar(); actionBar.setTitle("ActionBar Title"); actionBar.setBackgroundDrawable(getDrawable(R.drawable.ic_launcher_background)); actionBar.setCustomView(R.layout.activity_actionbar); actionBar.setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM); }
备注 是getSupportActionBar()还是默认的getActionBar(),还可以自定义title view
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 <style name="AppCompatActivity_ToolBarTheme" parent="Theme.AppCompat.Light"> <item name="windowActionBar">false</item> <item name="windowNoTitle">true</item> <item name="colorPrimary">@color/colorPrimary</item> <item name="colorPrimaryDark">@color/colorPrimaryDark</item> <item name="colorAccent">@color/colorAccent</item> <item name="android:textAllCaps">false</item> </style> <android.support.v7.widget.Toolbar android:id="@+id/toolbar" android:orientation="vertical" android:layout_width="match_parent" android:background="?attr/colorPrimary" android:layout_height="200dp" app:title="标题" android:minHeight="?attr/actionBarSize"> <TextView android:id="@+id/toolbar_view" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textColor="#ff0000" android:text="自定义View"/> </android.support.v7.widget.Toolbar> @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); //也可以这里设置toolbar Toolbar toolBar = findViewById(R.id.toolbar); //主标题,必须在setSupportActionBar之前设置,否则无效,如果放在其他位置,则直接setTitle即可 toolBar.setTitle("ToolBar Title"); //用toolbar替换actionbar setSupportActionBar(toolBar); }
备注 可以在xml设置属性,也以在代码中设置;还可以在xml添加view;还可以对Toolbar自定义;使用Toolbar要隐藏ActionBar;
ActionBar和ToolBar:使用详细点击
item属性释义 比较通用的几个属性,引用了网上的一个截图;更多详细见:各属性指定颜色的位置
状态栏背景色 Android4.4(< API 19) 在Android系统4.4以前,状态栏的背景色和字体颜色都是不能改变的,我们可以对 StatusBar 进行全屏或隐藏操作。
配置theme
1 android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
代码全屏
1 2 getWindow().setFlags(WindowManager.LayoutParams. FLAG_FULLSCREEN , WindowManager.LayoutParams. FLAG_FULLSCREEN);
Android4.4(API 19)- Android 5.0(< API 21)
theme:
1 2 3 4 <item name="android:windowTranslucentStatus">true</item> <!-- 失效 --> <item name="colorPrimaryDark">@color/colorPrimary</item>
代码:
1 getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
设置如上属性后,我们会发现状态栏的背景变了,其实不是变了,而是标题栏的布局延伸到了状态栏里。 如果是图片浸入的话:直接给TitleBar或者自定义view设置背景图即可。
1 2 Toolbar toolBar = findViewById(R.id.toolbar); toolBar.setBackgroundResource(R.mipmap.title_back);
Android 5.0(>= API 21)
theme:
1 <item name="colorPrimaryDark">@color/colorPrimary</item>
代码:
1 getWindow().setStatusBarColor(getResources().getColor(android.R.color.holo_red_light));
如果是图片浸入的话:直接在主题中设置状态栏背景色透明即可,同理直接给TitleBar或者自定义view设置背景图即可;效果图同上。
1 2 3 4 5 <item name="android:windowTranslucentStatus">true</item> <item name = "android:statusBarColor">@android:color/transparent</item> Toolbar toolBar = findViewById(R.id.toolbar); toolBar.setBackgroundResource(R.mipmap.title_back);
android:fitsSystemWindows=”true” 当我们设置了android:windowTranslucentStatus=true后,我们发现Toolbar内容被StatusBar覆盖,相当于Toolbar整体布局上移了,怎么解决?我们可以设置android:fitsSystemWindows=”true”,但是这时候我们发现,我们的StatusBar的背景色实效了。如何解决?我们就可以通过往Window窗口的decorView添加一个View,让它大小与系统状态栏一样,然后设置这个view的背景,就可以实现修改状态栏颜色的效果了。但是这种只适合修改StatusBar的背景色,如果是图片浸入,就不可以了。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 ViewGroup decorViewGroup = (ViewGroup) getWindow().getDecorView(); View statusBarView = new View(getWindow().getContext()); int statusBarHeight = getStatusBarHeight(getWindow().getContext()); FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, statusBarHeight); params.gravity = Gravity.TOP; statusBarView.setLayoutParams(params); statusBarView.setBackgroundResource(R.color.colorPrimary); decorViewGroup.addView(statusBarView); private static int getStatusBarHeight(Context context) { int statusBarHeight = 0; Resources res = context.getResources(); int resourceId = res.getIdentifier("status_bar_height", "dimen", "android"); if (resourceId > 0) { statusBarHeight = res.getDimensionPixelSize(resourceId); } return statusBarHeight; }
TitleBar图片浸入 我们从上面的效果图,可以看出,图片浸入时,相当于TitleBar移动到了状态栏的下面,这个时候我们标题可能与状态栏的图标重叠,那怎么办呢?上边说了android:fitsSystemWindows=”true”不行,需要设置状态栏背景色失效,其实我们这个时候,可以在TitleBar上添加一个和状态栏大小的透明view即可,TitleBar设置paddingTop 也可以,但是你需要重新设置TitleBar的高度,这样的话就不如第一种方案合适了。 设计一个xml,这个包含了TitleBar和默认的StatusBar的替代view。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical"> <ImageView android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_alignBottom="@+id/toolbar" android:layout_alignTop="@+id/statusBartop" android:scaleType="fitXY" android:src="@mipmap/title_back" /> <LinearLayout android:id="@+id/statusBartop" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="#00000000" android:orientation="horizontal" /> <android.support.v7.widget.Toolbar android:id="@+id/toolbar" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_below="@+id/statusBartop" > <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:text=" dkfslfjslfsjflsjflsf" android:textColor="@android:color/holo_red_dark" android:textSize="16dp" /> </android.support.v7.widget.Toolbar> </RelativeLayout>
然后我们在代码中进行设置即可:版本大于18,即4.4以上即可,4.4一下不存在沉浸式模式;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 int sysVersion = Build.VERSION.SDK_INT; if (sysVersion > Build.VERSION_CODES.JELLY_BEAN_MR2 ) { int result = 0; int resourceId = getResources().getIdentifier("status_bar_height", "dimen", "android"); if (resourceId > 0) { result = getResources().getDimensionPixelSize(resourceId); } LinearLayout toptop = this.findViewById(R.id.statusBartop); RelativeLayout.LayoutParams para = new RelativeLayout.LayoutParams(this.getWindowManager().getDefaultDisplay().getWidth(), result); //设置修改后的布局。 toptop.setLayoutParams(para); Toolbar toolbar = this.findViewById(R.id.toolbar); RelativeLayout.LayoutParams paraBar = new RelativeLayout.LayoutParams(this.getWindowManager().getDefaultDisplay().getWidth(), 150); paraBar.addRule(RelativeLayout.BELOW,R.id.statusBartop); toolbar.setLayoutParams(paraBar); }
最后别忘记设置
1 2 3 <item name="android:windowTranslucentStatus">true</item> 或者在代码中: getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
看下效果图:
Ursprünglicher Link: http://nunu03.github.io/2019/11/19/Android-沉浸式解析/
Copyright-Erklärung: 转载请注明出处.