前言:虽然状态栏颜色的改变是5.X之后的事情,但是现在市场上Android4.4机型数量依旧很多,所以为了让更多拥有Android4.4的机型也能体验到这一效果,所以今天就来实现这一效果,如果你对Android状态栏不懂的请移步上一篇文章:《Android开发之Android5.x的状态栏变色相关东西》,Android4.4以下的是无法实现这一效果的。
-------------------------------------分割线---------------------------------------------------------
第一种方式:
1.在属性样式里面设置(不推荐使用,因为兼容不好)
<item name="android:windowTranslucentStatus">true</item>
但是这种方式兼容性不太好所以不推荐使用,可以在代码里面解决:
getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
setContentView(R.layout.activity_main);
2.在最外层容器设置android:fitsSystemWindows="true",然后将最外层容器(也可以修改-android:windowBackground颜色)设置成状态栏想要的颜色,最后下面剩下的布局再包裹一层正常的背景颜色。
3.注意点:给Toolbar设置android:fitsSystemWindows="true",如果有ScrollView并且ScrollView里面有Edittext的时候,就会出现软键盘一弹起就会把toolbar拉下来。
会出现这种情况:
第二种方式:
1.在代码里面设置:
getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
setContentView(R.layout.activity_main);
2.设置toolbar的高度:
ViewGroup.LayoutParams params = toolbar.getLayoutParams();
int statusBarHeight = getStatusBarHeight(this);
params.height += statusBarHeight;
toolbar.setLayoutParams(params);
我们可以通过反射来获取状态栏的高度:
private int getStatusBarHeight(Context context) {
// 反射手机运行的类:android.R.dimen.status_bar_height.
int statusHeight = -1;
try {
Class<?> clazz = Class.forName("com.android.internal.R$dimen");
Object object = clazz.newInstance();
String heightStr = clazz.getField("status_bar_height").get(object).toString();
int height = Integer.parseInt(heightStr);
//dp-->px
statusHeight = context.getResources().getDimensionPixelSize(height);
} catch (Exception e) {
e.printStackTrace();
}
return statusHeight;
}
-------------------------------------分割线---------------------------------------------------------
1.在代码里面设置:
getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
setContentView(R.layout.activity_main);
2.修改Toolbar的PaddingTop:
toolbar.setPadding(toolbar.getPaddingLeft(),
toolbar.getPaddingTop() + getStatusBarHeight(this),
toolbar.getPaddingRight(),
toolbar.getPaddingBottom());
这里同样使用反射来获取状态栏高度。
-------------让4.4的虚拟导航NavigationBar也做出沉浸式效果-----------
2.动态设置底部View的高度为虚拟导航栏的高度:
View nav = findViewById(R.id.nav);
ViewGroup.LayoutParams p = nav.getLayoutParams();
p.height += getNavigationBarHeight(this);
nav.setLayoutParams(p);
同样通过反射来获取状态栏的高度
private int getNavigationBarHeight(Context context) {
// 反射手机运行的类:android.R.dimen.status_bar_height.
int navigationBarHeight = -1;
try {
Class<?> clazz = Class.forName("com.android.internal.R$dimen");
Object object = clazz.newInstance();
String heightStr = clazz.getField("navigation_bar_height").get(object).toString();
int height = Integer.parseInt(heightStr);
//dp-->px
navigationBarHeight = context.getResources().getDimensionPixelSize(height);
} catch (Exception e) {
e.printStackTrace();
}
return navigationBarHeight;
}
1.SDK版本不一样,两个区间:1. 大于5.0;2.=<4.4sdk<5.0
2.有的没有虚拟导航栏,判断是否有虚拟导航栏(源码里面有方法可以得到是否有虚拟导航,反射得到)
3.有的有虚拟导航,但是还可以开关,判断是否虚拟导航栏打开了
完整代码奉上:
写一个基类:
import android.content.Context;
import android.os.Build;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.annotation.RequiresApi;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.util.DisplayMetrics;
import android.view.Display;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
/**
* Created by Fly on 2017/5/9.
*/
public class BaseTranslucentActivity extends AppCompatActivity {
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//判断版本,如果[4.4,5.0]就设置状态栏和导航栏为透明
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT
&& Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
//设置状态栏的透明属性
getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
//设置虚拟导航栏为透明
getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
}
}
public void setOrChangeTranslucentColor(Toolbar toolbar, View bottomNavigationBar, int translucentPrimaryColor) {
//判断版本,如果[4.4,5.0)就设置状态栏和导航栏为透明
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT
&& Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
if (toolbar != null) {
//1、先设置toolbar的高度
ViewGroup.LayoutParams params = toolbar.getLayoutParams();
int statusBarHeight = getStatusBarHeight(this);
params.height += statusBarHeight;
toolbar.setLayoutParams(params);
//2、设置paddingtop,以达到状态栏不遮挡toolbar的内容
toolbar.setPadding(toolbar.getPaddingLeft(),
toolbar.getPaddingTop() + getStatusBarHeight(this),
toolbar.getPaddingRight(),
toolbar.getPaddingBottom());
//设置顶部的颜色
toolbar.setBackgroundColor(translucentPrimaryColor);
}
if (bottomNavigationBar != null) {
//解决低版本4.4+的虚拟导航栏的
if (hasNavigationBarShow(getWindowManager())) {
ViewGroup.LayoutParams p = bottomNavigationBar.getLayoutParams();
p.height += getNavigationBarHeight(this);
bottomNavigationBar.setLayoutParams(p);
//设置底部导航栏的颜色
bottomNavigationBar.setBackgroundColor(translucentPrimaryColor);
}
}
} else if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {
getWindow().setNavigationBarColor(translucentPrimaryColor);
getWindow().setStatusBarColor(translucentPrimaryColor);
}else {
//小于4.4的不处理
}
}
private int getNavigationBarHeight(Context context) {
return getSystemComponentDimen(this, "navigation_bar_height");
}
/**
* 获取状态栏的高度
*
* @param context
* @return
*/
private int getStatusBarHeight(Context context) {
// 反射手机运行的类:android.R.dimen.status_bar_height.
return getSystemComponentDimen(this, "status_bar_height");
}
private static int getSystemComponentDimen(Context context, String dimenName) {
// 反射手机运行的类:android.R.dimen.status_bar_height.
int statusHeight = -1;
try {
Class<?> clazz = Class.forName("com.android.internal.R$dimen");
Object object = clazz.newInstance();
String heightStr = clazz.getField(dimenName).get(object).toString();
int height = Integer.parseInt(heightStr);
//dp--->px
statusHeight = context.getResources().getDimensionPixelSize(height);
} catch (Exception e) {
e.printStackTrace();
}
return statusHeight;
}
@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR1)
private static boolean hasNavigationBarShow(WindowManager wm) {
Display display = wm.getDefaultDisplay();
DisplayMetrics outMetrics = new DisplayMetrics();
//获取整个屏幕的高度
display.getRealMetrics(outMetrics);
int heightPixels = outMetrics.heightPixels;
int widthPixels = outMetrics.widthPixels;
//获取内容展示部分的高度
outMetrics = new DisplayMetrics();
display.getMetrics(outMetrics);
int heightPixels2 = outMetrics.heightPixels;
int widthPixels2 = outMetrics.widthPixels;
int w = widthPixels - widthPixels2;
int h = heightPixels - heightPixels2;
return w > 0 || h > 0;//竖屏和横屏两种情况。
}
}
然后MainActivity类继承:
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.widget.Toolbar;
import android.view.View;
/**
* Created by Fly on 2017/5/9.
*/
public class MainActivity2 extends BaseTranslucentActivity {
private Toolbar toolbar;
private View nav;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
toolbar = (Toolbar) findViewById(R.id.toolbar);
nav = findViewById(R.id.nav);
setOrChangeTranslucentColor(toolbar, nav, getResources().getColor(R.color.colorPrimaryDark));
}
}
ok,赶紧在你手机上试一试吧!
--------------------------------敬请期待下一章。。。--------------------------------------------------------