Android 將App的內(nèi)容延伸到狀態(tài)欄/導(dǎo)航欄

來自我的CSDN博客:http://blog.csdn.net/dahaohan/article/details/52175190

看過Android的桌面應(yīng)用都是介樣的:

如何讓自己的應(yīng)用也達(dá)到這般效果呢每聪?這里就介紹幾種常用的方法以及它們之間的區(qū)別琳骡。

首先展示下此次demo的布局和初始狀態(tài):

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.example.jokerlee.androidlsample.MainActivity"
    android:background="@android:color/holo_green_dark"
    android:fitsSystemWindows="true">


    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:layout_centerHorizontal="true"
        android:text="Hello World."/>

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_centerHorizontal="true"
        android:text="Hello World."/>

</RelativeLayout>

初始效果圖如下:


透明狀態(tài)欄/導(dǎo)航欄##

使用這個(gè)方式首先要理解幾個(gè)概念,窗口層級以及窗口background/窗口透明:
Google在API-19 以及API-21新增對狀態(tài)欄/導(dǎo)航欄窗口透明和顏色的控制:

        getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
        getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
        getWindow().setStatusBarColor(blackColor);
        getWindow().setNavigationBarColor(blackColor);

對應(yīng)的在主題內(nèi)即可控制:

        <item name="android:statusBarColor">@android:color/transparent</item>
        <item name="android:navigationBarColor">@android:color/transparent</item>
        <item name="android:windowTranslucentStatus">true</item>
        <item name="android:windowTranslucentNavigation">true</item>

這里首先要明了這里狀態(tài)欄和導(dǎo)航欄窗口是系統(tǒng)級窗口而Activity對應(yīng)的時(shí)應(yīng)用窗口妙痹,它們屬于不同的窗口層級吉懊;
然后狀態(tài)欄/導(dǎo)航欄系統(tǒng)級窗口是在App應(yīng)用窗口之上庐橙,故而Activity應(yīng)用窗口雖然有整個(gè)屏幕的大小,但是可顯示內(nèi)容的區(qū)域得除去其上疊加的不透明的窗口區(qū)域借嗽。詳細(xì)的窗口計(jì)算繪制可參考大神老羅的博文:
Android窗口管理服務(wù)WindowManagerService計(jì)算Activity窗口大小的過程分析

下面來使用主題控制導(dǎo)航欄/狀態(tài)欄透明怕午,同時(shí)看看上述兩種設(shè)置透明的方式效果有何不同:

    <style name="TestTheme" parent="android:Theme.Material.NoActionBar">
        <!--下列兩行控制使得應(yīng)用窗口透明,用于展示一些差異-->
        <item name="android:windowBackground">@color/transparent</item>
        <item name="android:windowIsTranslucent">true</item>
        <!--設(shè)置導(dǎo)航欄/狀態(tài)欄窗口color為透明-->
        <item name="android:statusBarColor">@android:color/transparent</item>
        <item name="android:navigationBarColor">@android:color/transparent</item>

        <!--<item name="android:windowTranslucentStatus">true</item>-->
        <!--<item name="android:windowTranslucentNavigation">true</item>-->
    </style>

初始桌面和啟動Activity效果圖:


可以看到雖然導(dǎo)航欄/狀態(tài)欄透明了淹魄,當(dāng)時(shí)應(yīng)用窗口顯示的內(nèi)容依然只是除去了兩個(gè)系統(tǒng)窗口之外的區(qū)域郁惜,并沒有衍生到導(dǎo)航欄/狀態(tài)欄之下。

    //若是使用window flag控制導(dǎo)航欄/狀態(tài)欄透明
    <style name="TestTheme" parent="android:Theme.Material.NoActionBar">

        <!--下列兩行控制使得應(yīng)用窗口透明甲锡,用于展示一些差異-->
        <item name="android:windowBackground">@color/transparent</item>
        <item name="android:windowIsTranslucent">true</item>
        <!--設(shè)置導(dǎo)航欄/狀態(tài)欄窗口color為透明-->
        <!--<item name="android:statusBarColor">@android:color/transparent</item>-->
        <!--<item name="android:navigationBarColor">@android:color/transparent</item>-->

        <item name="android:windowTranslucentStatus">true</item>
        <item name="android:windowTranslucentNavigation">true</item>
    </style>

效果如下:


可以看到已經(jīng)將應(yīng)用的內(nèi)容布局延伸到導(dǎo)航欄/狀態(tài)欄下方了兆蕉,來看看關(guān)于android:windowTranslucentStatus
android:windowTranslucentNavigation的官方說明看看來理解其與設(shè)置color transparent的區(qū)別:

        /**
         * Window flag: request a translucent status bar with minimal system-provided
         * background protection.
         *
         * <p>This flag can be controlled in your theme through the
         * {@link android.R.attr#windowTranslucentStatus} attribute; this attribute
         * is automatically set for you in the standard translucent decor themes
         * such as
         * {@link android.R.style#Theme_Holo_NoActionBar_TranslucentDecor},
         * {@link android.R.style#Theme_Holo_Light_NoActionBar_TranslucentDecor},
         * {@link android.R.style#Theme_DeviceDefault_NoActionBar_TranslucentDecor}, and
         * {@link android.R.style#Theme_DeviceDefault_Light_NoActionBar_TranslucentDecor}.</p>
         *
         * <p>When this flag is enabled for a window, it automatically sets
         * the system UI visibility flags {@link View#SYSTEM_UI_FLAG_LAYOUT_STABLE} and
         * {@link View#SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN}.</p>
         */
         public static final int FLAG_TRANSLUCENT_STATUS = 0x04000000;

         * <p>When this flag is enabled for a window, it automatically sets
         * the system UI visibility flags {@link View#SYSTEM_UI_FLAG_LAYOUT_STABLE} and
         * {@link View#SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION}.</p>
         */
        public static final int FLAG_TRANSLUCENT_NAVIGATION = 0x08000000;

根據(jù)FLAG的說明,可以看出設(shè)置該標(biāo)志位等同于View申請?jiān)O(shè)置:

        //使得布局延伸到狀態(tài)欄和導(dǎo)航欄區(qū)域
        window.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
                | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
                | View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
        //透明狀態(tài)欄/導(dǎo)航欄
        window.setStatusBarColor(Color.TRANSPARENT);
        window.setNavigationBarColor(Color.TRANSPARENT);
        //這樣的效果跟上述的主題設(shè)置效果類似

PS:從效果圖看缤沦,雖然布局延伸到狀態(tài)欄導(dǎo)航欄區(qū)域虎韵,但是相應(yīng)的內(nèi)容“hello world”文字也被狀態(tài)欄/導(dǎo)航欄遮住了。在布局根視圖設(shè)置fitsSystemWindows為true可以使得缸废,系統(tǒng)自動為視圖添加一個(gè)狀態(tài)欄/導(dǎo)航欄高度的padding:

rootView.setFitsSystemWindows(true);
//或者xml view標(biāo)簽加入
android:fitsSystemWindows="true"

效果如下:


查看SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION 和 SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN的說明包蓝,可以發(fā)現(xiàn)其實(shí)還有兩個(gè)非常接近的FLAG:

public static final int SYSTEM_UI_FLAG_FULLSCREEN = 0x00000004;
public static final int SYSTEM_UI_FLAG_HIDE_NAVIGATION = 0x00000002;
//這兩flag跟上述主要區(qū)別在于驶社,在設(shè)置和取消flag時(shí),會引起重新布局测萎,也就是當(dāng)從SYSTEM_UI_FLAG_FULLSCREEN模式
//退出時(shí)亡电,activity的內(nèi)容顯示窗口會變小,看起來就是這個(gè)布局內(nèi)容畫面會上移/下移硅瞧。

根據(jù)官方的說明提示份乒,SYSTEM_UI_FLAG_FULLSCREEN / SYSTEM_UI_FLAG_HIDE_NAVIGATION主要用于動態(tài)切換隱藏/顯示系統(tǒng)導(dǎo)航欄/狀態(tài)欄;例如書籍閱讀應(yīng)用/視頻播放應(yīng)用等腕唧。而像游戲類的全屏應(yīng)用則推薦使用window flag或辖。

API-19以下的如何實(shí)現(xiàn)?

上述的透明導(dǎo)航欄/狀態(tài)欄等API基本是需要API-19或是API-21才能使用的枣接,這里還有一種API-1的方案能夠?qū)崿F(xiàn)布局內(nèi)容全屏:

        getWindow().addFlags(WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN);
        getWindow().addFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);

實(shí)際上只需要設(shè)置FLAG_LAYOUT_NO_LIMITS就足夠了颂暇;這FLAG是看Android原生的Launcher / Keyguard源碼,看到有用到如此設(shè)置但惶,其窗口設(shè)置具體原理我也沒有弄清..... 有大神了解可以指點(diǎn)下蟀架。

PS:這個(gè)套路下,使用fitsSystemWindows="true"是無效的榆骚,智能自己控制號布局位置片拍。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市妓肢,隨后出現(xiàn)的幾起案子捌省,更是在濱河造成了極大的恐慌,老刑警劉巖碉钠,帶你破解...
    沈念sama閱讀 206,013評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件纲缓,死亡現(xiàn)場離奇詭異,居然都是意外死亡喊废,警方通過查閱死者的電腦和手機(jī)祝高,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,205評論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來污筷,“玉大人工闺,你說我怎么就攤上這事“曛” “怎么了陆蟆?”我有些...
    開封第一講書人閱讀 152,370評論 0 342
  • 文/不壞的土叔 我叫張陵,是天一觀的道長惋增。 經(jīng)常有香客問我叠殷,道長,這世上最難降的妖魔是什么诈皿? 我笑而不...
    開封第一講書人閱讀 55,168評論 1 278
  • 正文 為了忘掉前任林束,我火速辦了婚禮像棘,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘壶冒。我一直安慰自己缕题,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,153評論 5 371
  • 文/花漫 我一把揭開白布依痊。 她就那樣靜靜地躺著,像睡著了一般怎披。 火紅的嫁衣襯著肌膚如雪胸嘁。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 48,954評論 1 283
  • 那天凉逛,我揣著相機(jī)與錄音性宏,去河邊找鬼。 笑死状飞,一個(gè)胖子當(dāng)著我的面吹牛毫胜,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播诬辈,決...
    沈念sama閱讀 38,271評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼酵使,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了焙糟?” 一聲冷哼從身側(cè)響起口渔,我...
    開封第一講書人閱讀 36,916評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎穿撮,沒想到半個(gè)月后缺脉,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,382評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡悦穿,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,877評論 2 323
  • 正文 我和宋清朗相戀三年攻礼,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片栗柒。...
    茶點(diǎn)故事閱讀 37,989評論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡礁扮,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出瞬沦,到底是詐尸還是另有隱情深员,我是刑警寧澤,帶...
    沈念sama閱讀 33,624評論 4 322
  • 正文 年R本政府宣布蛙埂,位于F島的核電站倦畅,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏绣的。R本人自食惡果不足惜叠赐,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,209評論 3 307
  • 文/蒙蒙 一欲账、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧芭概,春花似錦赛不、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,199評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至惹苗,卻和暖如春殿较,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背桩蓉。 一陣腳步聲響...
    開封第一講書人閱讀 31,418評論 1 260
  • 我被黑心中介騙來泰國打工淋纲, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人院究。 一個(gè)月前我還...
    沈念sama閱讀 45,401評論 2 352
  • 正文 我出身青樓洽瞬,卻偏偏與公主長得像,于是被迫代替她去往敵國和親业汰。 傳聞我的和親對象是個(gè)殘疾皇子伙窃,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,700評論 2 345

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