沉浸式設計之狀態(tài)欄和導航欄適配

前言

第一次寫博客感覺有點激動。最近在學習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;

}

}

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市吨铸,隨后出現(xiàn)的幾起案子行拢,更是在濱河造成了極大的恐慌,老刑警劉巖诞吱,帶你破解...
    沈念sama閱讀 221,406評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件舟奠,死亡現(xiàn)場離奇詭異,居然都是意外死亡房维,警方通過查閱死者的電腦和手機沼瘫,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,395評論 3 398
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來咙俩,“玉大人耿戚,你說我怎么就攤上這事“⒊茫” “怎么了膜蛔?”我有些...
    開封第一講書人閱讀 167,815評論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長脖阵。 經(jīng)常有香客問我皂股,道長,這世上最難降的妖魔是什么命黔? 我笑而不...
    開封第一講書人閱讀 59,537評論 1 296
  • 正文 為了忘掉前任呜呐,我火速辦了婚禮,結(jié)果婚禮上悍募,老公的妹妹穿的比我還像新娘蘑辑。我一直安慰自己,他們只是感情好坠宴,可當我...
    茶點故事閱讀 68,536評論 6 397
  • 文/花漫 我一把揭開白布以躯。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪忧设。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,184評論 1 308
  • 那天颠通,我揣著相機與錄音址晕,去河邊找鬼。 笑死顿锰,一個胖子當著我的面吹牛谨垃,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播硼控,決...
    沈念sama閱讀 40,776評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼刘陶,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了牢撼?” 一聲冷哼從身側(cè)響起匙隔,我...
    開封第一講書人閱讀 39,668評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎熏版,沒想到半個月后纷责,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,212評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡撼短,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,299評論 3 340
  • 正文 我和宋清朗相戀三年再膳,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片曲横。...
    茶點故事閱讀 40,438評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡喂柒,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出禾嫉,到底是詐尸還是另有隱情灾杰,我是刑警寧澤,帶...
    沈念sama閱讀 36,128評論 5 349
  • 正文 年R本政府宣布夭织,位于F島的核電站吭露,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏尊惰。R本人自食惡果不足惜讲竿,卻給世界環(huán)境...
    茶點故事閱讀 41,807評論 3 333
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望弄屡。 院中可真熱鬧题禀,春花似錦、人聲如沸膀捷。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,279評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至秀仲,卻和暖如春融痛,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背神僵。 一陣腳步聲響...
    開封第一講書人閱讀 33,395評論 1 272
  • 我被黑心中介騙來泰國打工雁刷, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人保礼。 一個月前我還...
    沈念sama閱讀 48,827評論 3 376
  • 正文 我出身青樓沛励,卻偏偏與公主長得像,于是被迫代替她去往敵國和親炮障。 傳聞我的和親對象是個殘疾皇子目派,可洞房花燭夜當晚...
    茶點故事閱讀 45,446評論 2 359

推薦閱讀更多精彩內(nèi)容