沉浸式設(shè)計(jì)之狀態(tài)欄和導(dǎo)航欄適配

前言

第一次寫博客感覺有點(diǎn)激動(dòng)。最近在學(xué)習(xí)android的沉浸式設(shè)計(jì),之前在項(xiàng)目開發(fā)中對于沉 浸式也遇到了許多坑,今天索性把這塊東西重寫梳理下,希望可以幫助一些在這方面遇到問題的朋友

沉浸式主要針對的是狀態(tài)欄和導(dǎo)航欄的背景設(shè)置,如果對于我們的產(chǎn)品不進(jìn)行沉浸式設(shè)計(jì),那么我們的產(chǎn)品看上去就會(huì)顯得有點(diǎn)丑陋。頭部和底部和中間部分在整體上有點(diǎn)不搭

內(nèi)容

一? 對于android 5.0以及5.0以上,我們可以直接可以這樣用代碼進(jìn)行設(shè)置

? ? getWindow().setStatusBarColor(styleColor);

? ? ? getWindow().setNavigationBarColor(styleColor); 比較簡單,這里就不在多講了

二? 對于5.0以下,4.4以上,我們需要進(jìn)行特殊的處理。我們要分別獲取狀態(tài)欄和導(dǎo)航欄的高度,然后對于狀態(tài)欄我們只要把toolbar設(shè)置下paddingTop就ok了,而對于導(dǎo)航欄,我們需要?jiǎng)討B(tài)的給下面放置一個(gè)view,然后給這個(gè)view設(shè)置背景顏色,下面,進(jìn)行詳細(xì)的講解下

1.首先我們要把狀態(tài)欄和導(dǎo)航欄的背景設(shè)置為透明色,代碼如下

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.然后我們分別獲取狀態(tài)欄和導(dǎo)航欄的高度

//獲取狀態(tài)欄的高度,因?yàn)楝F(xiàn)在市面的android手機(jī)型號很多,然后,不同手機(jī)的狀態(tài)欄高度可能不一樣,status_bar_height,navigation_bar_height的高度我們可以到對應(yīng)的sdk里面的dimens,xml中進(jìn)行查看

查看路徑:(\Android\Sdk\platforms\xx\data\res\values\dimens.xml)這里的xx代表sdk的版本,android-21或android-22,或者其他版本,所以我們就可以用反射進(jìn)行動(dòng)態(tài)獲取statusBar和navigationBar的高度,代碼如下

1>//獲取狀態(tài)欄高度

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>在給導(dǎo)航欄設(shè)置沉浸式時(shí),我們需要先判斷是否有導(dǎo)航欄,因?yàn)楝F(xiàn)在的手機(jī)廠商給我們帶來的適配上的痛,你懂得,有的手機(jī)廠商把導(dǎo)航欄做成了物理按鍵。我們可以利用手機(jī)實(shí)際屏幕的高度(手機(jī)物理高度)和手機(jī)的內(nèi)容高度進(jìn)行比較,進(jìn)而判斷是否包含導(dǎo)航欄。如果實(shí)際物理的高度大于屏幕內(nèi)容的高度,則包含導(dǎo)航欄,代碼如下:

@RequiresApi(api= Build.VERSION_CODES.JELLY_BEAN_MR1)

private boolean? ? haveNavgtion() {

//屏幕的高度? 真實(shí)物理的屏幕

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;

//屏幕內(nèi)容高度? 顯示內(nèi)容的屏幕

intw = widthDisplay - contentDisplayWidth;

//哪一方大于0? 就有導(dǎo)航欄

inth = heightDisplay - contentDisplay;

return? w >0|| h >0;

}

假如判斷手機(jī)有導(dǎo)航欄,那么,我么這里就可以去獲取導(dǎo)航欄的高度了,獲取導(dǎo)航欄的高度和獲取狀態(tài)欄的高度,方法基本上一樣,代碼如下:

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.狀態(tài)欄和導(dǎo)航欄的高度我們已經(jīng)獲取到,下面我們就開始分別對狀態(tài)欄和導(dǎo)航欄進(jìn)行沉浸處理了

1>.對于狀態(tài)欄,上面我們已經(jīng)提到可以把toolbar設(shè)置下PaddingTop,代碼如下:

toolbar.setPadding(0,toolbar.getPaddingTop() + statusHeight,0,0);

(這里的statusHeight是狀態(tài)欄的高度)

2.>對于導(dǎo)航欄,我們這樣進(jìn)行處理

ViewGroup.LayoutParams layoutParams = bottomView.getLayoutParams();

layoutParams.height+= getNavigationHeight();

Log.i("tuch","getNavigationHeight? "+ getNavigationHeight());

bottomView.setLayoutParams(layoutParams);

bottomView.setBackgroundColor(styleColor);

三.對于android 19(4.4)以下的我們沒有辦法進(jìn)行沉浸式處理,可以放棄了。

好了,到此就結(jié)束了,如果有錯(cuò)的地方希望大家?guī)兔χ赋觥?/p>

完整代碼如下:

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);

//下面的導(dǎo)航欄

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() {

//屏幕的高度? 真實(shí)物理的屏幕

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;

//屏幕內(nèi)容高度? 顯示內(nèi)容的屏幕

intw = widthDisplay - contentDisplayWidth;

//哪一方大于0? 就有導(dǎo)航欄

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;

}

}

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容