前言
第一次寫博客感覺有點激動。最近在學習android的沉浸式設計毅整,之前在項目開發(fā)中對于沉 浸式也遇到了許多坑橘忱,今天索性把這塊東西重寫梳理下蓖墅,希望可以幫助一些在這方面遇到問題的朋友
沉浸式主要針對的是狀態(tài)欄和導航欄的背景設置绿聘,如果對于我們的產(chǎn)品不進行沉浸式設計庸队,那么我們的產(chǎn)品看上去就會顯得有點丑陋箩祥。頭部和底部和中間部分在整體上有點不搭
內(nèi)容
一? 對于android 5.0以及5.0以上两芳,我們可以直接可以這樣用代碼進行設置
? ? getWindow().setStatusBarColor(styleColor);
? ? ? getWindow().setNavigationBarColor(styleColor); 比較簡單撵孤,這里就不在多講了
二? 對于5.0以下迈着,4.4以上,我們需要進行特殊的處理邪码。我們要分別獲取狀態(tài)欄和導航欄的高度裕菠,然后對于狀態(tài)欄我們只要把toolbar設置下paddingTop就ok了,而對于導航欄闭专,我們需要動態(tài)的給下面放置一個view奴潘,然后給這個view設置背景顏色,下面影钉,進行詳細的講解下
1.首先我們要把狀態(tài)欄和導航欄的背景設置為透明色画髓,代碼如下
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)欄和導航欄的高度
//獲取狀態(tài)欄的高度,因為現(xiàn)在市面的android手機型號很多斧拍,然后雀扶,不同手機的狀態(tài)欄高度可能不一樣,status_bar_height肆汹,navigation_bar_height的高度我們可以到對應的sdk里面的dimens,xml中進行查看
查看路徑:(\Android\Sdk\platforms\xx\data\res\values\dimens.xml)這里的xx代表sdk的版本愚墓,android-21或android-22,或者其他版本昂勉,所以我們就可以用反射進行動態(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>在給導航欄設置沉浸式時,我們需要先判斷是否有導航欄岗照,因為現(xiàn)在的手機廠商給我們帶來的適配上的痛村象,你懂得,有的手機廠商把導航欄做成了物理按鍵攒至。我們可以利用手機實際屏幕的高度(手機物理高度)和手機的內(nèi)容高度進行比較厚者,進而判斷是否包含導航欄。如果實際物理的高度大于屏幕內(nèi)容的高度迫吐,則包含導航欄库菲,代碼如下:
@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;
//屏幕內(nèi)容高度? 顯示內(nèi)容的屏幕
intw = widthDisplay - contentDisplayWidth;
//哪一方大于0? 就有導航欄
inth = heightDisplay - contentDisplay;
return? w >0|| h >0;
}
假如判斷手機有導航欄,那么志膀,我么這里就可以去獲取導航欄的高度了熙宇,獲取導航欄的高度和獲取狀態(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)欄和導航欄的高度我們已經(jīng)獲取到烫止,下面我們就開始分別對狀態(tài)欄和導航欄進行沉浸處理了
1>.對于狀態(tài)欄蒋荚,上面我們已經(jīng)提到可以把toolbar設置下PaddingTop,代碼如下:
toolbar.setPadding(0,toolbar.getPaddingTop() + statusHeight,0,0);
(這里的statusHeight是狀態(tài)欄的高度)
2.>對于導航欄馆蠕,我們這樣進行處理
ViewGroup.LayoutParams layoutParams = bottomView.getLayoutParams();
layoutParams.height+= getNavigationHeight();
Log.i("tuch","getNavigationHeight? "+ getNavigationHeight());
bottomView.setLayoutParams(layoutParams);
bottomView.setBackgroundColor(styleColor);
三.對于android 19(4.4)以下的我們沒有辦法進行沉浸式處理期升,可以放棄了。
好了荆几,到此就結(jié)束了吓妆,如果有錯的地方希望大家?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);
//下面的導航欄
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;
//屏幕內(nèi)容高度? 顯示內(nèi)容的屏幕
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;
}
}