沉浸式设计之状态栏和导航栏适配

前言

第一次写博客感觉有点激动。最近在学习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;

}

}

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 210,978评论 6 490
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 89,954评论 2 384
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 156,623评论 0 345
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,324评论 1 282
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,390评论 5 384
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,741评论 1 289
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,892评论 3 405
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,655评论 0 266
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,104评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,451评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,569评论 1 340
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,254评论 4 328
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,834评论 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,725评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,950评论 1 264
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,260评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,446评论 2 348

推荐阅读更多精彩内容