前言
第一次写博客感觉有点激动。最近在学习android的沉浸式设计,之前在项目开发中对于沉 浸式也遇到了许多坑,今天索性把这块东西重写梳理下,希望可以帮助一些在这方面遇到问题的朋友
沉浸式主要针对的是状态栏和导航栏的背景设置,如果对于我们的产品不进行沉浸式设计,那么我们的产品看上去就会显得有点丑陋。头部和底部和中间部分在整体上有点不搭
内容
一 对于android 5.0以及5.0以上,我们可以直接可以这样用代码进行设置
getWindow().setStatusBarColor(styleColor);
getWindow().setNavigationBarColor(styleColor); 比较简单,这里就不在多讲了
二 对于5.0以下,4.4以上,我们需要进行特殊的处理。我们要分别获取状态栏和导航栏的高度,然后对于状态栏我们只要把toolbar设置下paddingTop就ok了,而对于导航栏,我们需要动态的给下面放置一个view,然后给这个view设置背景颜色,下面,进行详细的讲解下
1.首先我们要把状态栏和导航栏的背景设置为透明色,代码如下
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);
}
2.然后我们分别获取状态栏和导航栏的高度
//获取状态栏的高度,因为现在市面的android手机型号很多,然后,不同手机的状态栏高度可能不一样,status_bar_height,navigation_bar_height的高度我们可以到对应的sdk里面的dimens,xml中进行查看
查看路径:(\Android\Sdk\platforms\xx\data\res\values\dimens.xml)这里的xx代表sdk的版本,android-21或android-22,或者其他版本,所以我们就可以用反射进行动态获取statusBar和navigationBar的高度,代码如下
1>//获取状态栏高度
private intgetStatusHeight() {
intheight = -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();
height = Integer.parseInt(heightStr);
//dp--px
height = getResources().getDimensionPixelSize(height);
}catch(ClassNotFoundException e) {
e.printStackTrace();
}catch(InstantiationException e) {
e.printStackTrace();
}catch(IllegalAccessException e) {
e.printStackTrace();
}catch(NoSuchFieldException e) {
e.printStackTrace();
}
returnheight;
}
2>在给导航栏设置沉浸式时,我们需要先判断是否有导航栏,因为现在的手机厂商给我们带来的适配上的痛,你懂得,有的手机厂商把导航栏做成了物理按键。我们可以利用手机实际屏幕的高度(手机物理高度)和手机的内容高度进行比较,进而判断是否包含导航栏。如果实际物理的高度大于屏幕内容的高度,则包含导航栏,代码如下:
@RequiresApi(api= Build.VERSION_CODES.JELLY_BEAN_MR1)
private boolean haveNavgtion() {
//屏幕的高度 真实物理的屏幕
Display display = getWindowManager().getDefaultDisplay();
DisplayMetrics displayMetrics =newDisplayMetrics();
display.getRealMetrics(displayMetrics);
intheightDisplay = displayMetrics.heightPixels;
//为了防止横屏
intwidthDisplay = displayMetrics.widthPixels;
DisplayMetrics contentDisplaymetrics =newDisplayMetrics();
display.getMetrics(contentDisplaymetrics);
intcontentDisplay = contentDisplaymetrics.heightPixels;
intcontentDisplayWidth = contentDisplaymetrics.widthPixels;
//屏幕内容高度 显示内容的屏幕
intw = widthDisplay - contentDisplayWidth;
//哪一方大于0 就有导航栏
inth = heightDisplay - contentDisplay;
return w >0|| h >0;
}
假如判断手机有导航栏,那么,我么这里就可以去获取导航栏的高度了,获取导航栏的高度和获取状态栏的高度,方法基本上一样,代码如下:
private intgetNavigationHeight() {
intheight = -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();
height = Integer.parseInt(heightStr);
//dp--px
height = getResources().getDimensionPixelSize(height);
}catch(ClassNotFoundException e) {
e.printStackTrace();
}catch(InstantiationException e) {
e.printStackTrace();
}catch(IllegalAccessException e) {
e.printStackTrace();
}catch(NoSuchFieldException e) {
e.printStackTrace();
}
returnheight;
}
3.状态栏和导航栏的高度我们已经获取到,下面我们就开始分别对状态栏和导航栏进行沉浸处理了
1>.对于状态栏,上面我们已经提到可以把toolbar设置下PaddingTop,代码如下:
toolbar.setPadding(0,toolbar.getPaddingTop() + statusHeight,0,0);
(这里的statusHeight是状态栏的高度)
2.>对于导航栏,我们这样进行处理
ViewGroup.LayoutParams layoutParams = bottomView.getLayoutParams();
layoutParams.height+= getNavigationHeight();
Log.i("tuch","getNavigationHeight "+ getNavigationHeight());
bottomView.setLayoutParams(layoutParams);
bottomView.setBackgroundColor(styleColor);
三.对于android 19(4.4)以下的我们没有办法进行沉浸式处理,可以放弃了。
好了,到此就结束了,如果有错的地方希望大家帮忙指出。
完整代码如下:
importandroid.graphics.Color;
importandroid.os.Build;
importandroid.os.Bundle;
importandroid.support.annotation.Nullable;
importandroid.support.annotation.RequiresApi;
importandroid.support.v7.app.AppCompatActivity;
importandroid.support.v7.widget.Toolbar;
importandroid.util.DisplayMetrics;
importandroid.util.Log;
importandroid.view.Display;
importandroid.view.View;
importandroid.view.ViewGroup;
importandroid.view.WindowManager;
/**
* Created by Administrator on 2017/7/10 0010.
*/
public classBaseActivityextendsAppCompatActivity {
@Override
protected voidonCreate(@NullableBundle savedInstanceState) {
super.onCreate(savedInstanceState);
//setContentView之前 全屏
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);
}
}
/**
* 5.0 4.4
*
*@paramtoolbar
*@paramstyleColor
*/
public voidsetToolBarStyle(Toolbar toolbar,View bottomView, intstyleColor) {
// 5.0 4.4
if(Build.VERSION.SDK_INT>= Build.VERSION_CODES.KITKAT
&& Build.VERSION.SDK_INT< Build.VERSION_CODES.LOLLIPOP) {
if(toolbar !=null) {
intstatusHeight = getStatusHeight();
Log.i("tuch"," statusHeight "+ statusHeight);
//第二种
toolbar.setPadding(0,toolbar.getPaddingTop() + statusHeight,0,0);
//下面的导航栏
if(haveNavgtion()) {
ViewGroup.LayoutParams layoutParams = bottomView.getLayoutParams();
layoutParams.height+= getNavigationHeight();
Log.i("tuch","getNavigationHeight "+ getNavigationHeight());
bottomView.setLayoutParams(layoutParams);
bottomView.setBackgroundColor(styleColor);
}
}
}else if(Build.VERSION.SDK_INT>= Build.VERSION_CODES.LOLLIPOP) {
getWindow().setStatusBarColor(styleColor);
getWindow().setNavigationBarColor(styleColor);
}else{
//没救了
}
}
private intgetNavigationHeight() {
intheight = -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();
height = Integer.parseInt(heightStr);
//dp--px
height = getResources().getDimensionPixelSize(height);
}catch(ClassNotFoundException e) {
e.printStackTrace();
}catch(InstantiationException e) {
e.printStackTrace();
}catch(IllegalAccessException e) {
e.printStackTrace();
}catch(NoSuchFieldException e) {
e.printStackTrace();
}
returnheight;
}
@RequiresApi(api= Build.VERSION_CODES.JELLY_BEAN_MR1)
private booleanhaveNavgtion() {
//屏幕的高度 真实物理的屏幕
Display display = getWindowManager().getDefaultDisplay();
DisplayMetrics displayMetrics =newDisplayMetrics();
display.getRealMetrics(displayMetrics);
intheightDisplay = displayMetrics.heightPixels;
//为了防止横屏
intwidthDisplay = displayMetrics.widthPixels;
DisplayMetrics contentDisplaymetrics =newDisplayMetrics();
display.getMetrics(contentDisplaymetrics);
intcontentDisplay = contentDisplaymetrics.heightPixels;
intcontentDisplayWidth = contentDisplaymetrics.widthPixels;
//屏幕内容高度 显示内容的屏幕
intw = widthDisplay - contentDisplayWidth;
//哪一方大于0 就有导航栏
inth = heightDisplay - contentDisplay;
returnw >0|| h >0;
}
private intgetStatusHeight() {
intheight = -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();
height = Integer.parseInt(heightStr);
//dp--px
height = getResources().getDimensionPixelSize(height);
}catch(ClassNotFoundException e) {
e.printStackTrace();
}catch(InstantiationException e) {
e.printStackTrace();
}catch(IllegalAccessException e) {
e.printStackTrace();
}catch(NoSuchFieldException e) {
e.printStackTrace();
}
returnheight;
}
}