關于如何實現(xiàn)Android透明狀態(tài)欄的總結

開門見山。
原來做的效果奏属,如下圖(頂部有一條明顯的橙色狀態(tài)欄):


a1.gif

改過之后(頂部狀態(tài)欄是透明的):


p2.gif

我發(fā)現(xiàn)網上寫的一些文章跨跨,不夠簡潔明了潮峦,我整理了一下囱皿,復制粘貼一下就可以在項目中運用。

首先忱嘹,在你的Activity中添加下面四個方法(或者封裝在一個工具類中)

   /**
     * 全透狀態(tài)欄
     */
    protected void setStatusBarFullTransparent() {
        if (Build.VERSION.SDK_INT >= 21) {//21表示5.0
            Window window = getWindow();
            window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
            window.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
                    | View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
            window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
            window.setStatusBarColor(Color.TRANSPARENT);
        } else if (Build.VERSION.SDK_INT >= 19) {//19表示4.4
            getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
            //虛擬鍵盤也透明
            //getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
        }
    }

    /**
     * 半透明狀態(tài)欄
     */
    protected void setHalfTransparent() {

        if (Build.VERSION.SDK_INT >= 21) {//21表示5.0
            View decorView = getWindow().getDecorView();
            int option = View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_STABLE;
            decorView.setSystemUiVisibility(option);
            getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);

        } else if (Build.VERSION.SDK_INT >= 19) {//19表示4.4
            getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
            //虛擬鍵盤也透明
            // getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
        }
    }

    /**
     * 如果需要內容緊貼著StatusBar
     * 應該在對應的xml布局文件中嘱腥,設置根布局fitsSystemWindows=true。
     */
    private View contentViewGroup;

    protected void setFitSystemWindow(boolean fitSystemWindow) {
        if (contentViewGroup == null) {
            contentViewGroup = ((ViewGroup) findViewById(android.R.id.content)).getChildAt(0);
        }
        contentViewGroup.setFitsSystemWindows(fitSystemWindow);
    }

    /**
     * 為了兼容4.4的抽屜布局->透明狀態(tài)欄
     */
    protected void setDrawerLayoutFitSystemWindow() {
        if (Build.VERSION.SDK_INT == 19) {//19表示4.4
            int statusBarHeight = getStatusHeight(this);
            if (contentViewGroup == null) {
                contentViewGroup = ((ViewGroup) findViewById(android.R.id.content)).getChildAt(0);
            }
            if (contentViewGroup instanceof DrawerLayout) {
                DrawerLayout drawerLayout = (DrawerLayout) contentViewGroup;
                drawerLayout.setClipToPadding(true);
                drawerLayout.setFitsSystemWindows(false);
                for (int i = 0; i < drawerLayout.getChildCount(); i++) {
                    View child = drawerLayout.getChildAt(i);
                    child.setFitsSystemWindows(false);
                    child.setPadding(0,statusBarHeight, 0, 0);
                }

            }
        }
    }

然后拘悦,在Activity的onCreate()方法中調用即可齿兔。示例如下

Activity

public class TestActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_test);

        setHalfTransparent();
        setFitSystemWindow(false);
    }

    protected void setHalfTransparent()...
    protected void setStatusBarFullTransparent()...
    protected void setFitSystemWindow()...
    protected void setDrawerLayoutFitSystemWindow()...
}

布局文件

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout android:id="@+id/drawerLayout"
              xmlns:android="http://schemas.android.com/apk/res/android"
              android:layout_width="match_parent"
              android:layout_height="match_parent"
              android:background="@drawable/bg_start">


    <Button
        android:id="@+id/button"
        android:layout_width="100dp"
        android:layout_height="40dp"
        android:layout_marginLeft="50dp"
        android:background="#F86254"
        android:text="button"
        android:textColor="@color/white" />

</LinearLayout>

1.未做任何設置

可見,Android5.0以上由于默認是Material Design础米,頂部是藍色狀態(tài)欄分苇。而5.0以下,默認都是黑色屁桑,而且無法修改医寿。


nothing.png

2.半透明狀態(tài)欄,fitsSystemWindows=false

@Override
public void init(Bundle savedInstanceState) {
    setHalfTransparent();
    setFitSystemWindow(false);
}

half_not_fit.png

可見蘑斧,5.0以上藍色狀態(tài)欄沒了靖秩,變成了半透明的黑色,而內容區(qū)域則有了全屏的效果竖瘾。
但是也要知道一點沟突,那個紅色的TextView,原來是緊貼著狀態(tài)欄,現(xiàn)在是緊貼著屏幕的上邊緣捕传,這樣就導致惠拭,內容被遮擋。解決這個問題需要一個關鍵的屬性是setFitSystemWindow=true庸论,追蹤源碼可知职辅,它可以讓我們的布局今野,paddingTop等于狀態(tài)欄的高度,這樣紅色TextView的位置就會向下移罐农,從而不會被遮擋条霜。

3.半透明狀態(tài)欄,fitsSystemWindows=true

@Override
public void init(Bundle savedInstanceState) {
    setHalfTransparent();
    setFitSystemWindow(true);
}
half_fit.png

此時紅色的TextView涵亏,位于狀態(tài)欄下方宰睡。

4.全透明狀態(tài)欄,fitsSystemWindows=false

setStatusBarFullTransparent();
setFitSystemWindow(false);
full_no_fit.png

全透明和半透明的區(qū)別在于气筋,狀態(tài)欄是否具有淡黑色的背景拆内,根據(jù)項目需求合理運用。

5.全透明狀態(tài)欄宠默,fitsSystemWindows=true

setStatusBarFullTransparent();
setFitSystemWindow(true);
full_fit.png

6.DrawerLayout如何使用

直接使用上述方式麸恍,在4.4系統(tǒng)上會出現(xiàn)異常,因此我們需要進行適配搀矫。
修改xml文件抹沪,DrawerLayout需要添加fitsSystemWindows和clipToPadding屬性,DrawerLayout布局里的一級布局瓤球,都需設置fitsSystemWindows=true融欧。

<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout android:id="@+id/drawerLayout"
                                        xmlns:android="http://schemas.android.com/apk/res/android"
                                        android:layout_width="match_parent"
                                        android:fitsSystemWindows="true"
                                        android:clipToPadding="false"
                                        android:layout_height="match_parent">

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:fitsSystemWindows="true"
        android:background="@drawable/bg_start"
        android:orientation="vertical">


        <Button
            android:id="@+id/button"
            android:layout_width="100dp"
            android:layout_height="wrap_content"
            android:background="#F86254"
            android:text="show"
            android:textColor="@color/white" />

    </RelativeLayout>

    <FrameLayout
        android:id="@+id/sideLayout"
        android:layout_width="300dp"
        android:fitsSystemWindows="true"
        android:layout_height="match_parent"
        android:layout_gravity="end"
        android:background="@drawable/bg_test">

        <Button
            android:layout_width="100dp"
            android:layout_height="30dp"
            android:background="#F86254"
            android:text="button"
            android:textColor="@color/white" />
    </FrameLayout>

</android.support.v4.widget.DrawerLayout>
  1. 全透明狀態(tài)欄,fitsSystemWindows=false
setStatusBarFullTransparent();
drawerlayout_nofit.png
  1. DrawerLayout全透明狀態(tài)欄卦羡,fitsSystemWindows=true
setStatusBarFullTransparent();
setDrawerLayoutFitSystemWindow();
drawerlayout.png

7.可能會錯誤的地方

本來我們有一個界面:



然后按照上面的抑片,添加了代碼之后

setStatusBarFullTransparent();
setFitSystemWindow(true);
image.png

然后你提刀來問樓主肺稀,這是什么鬼!!蚓峦!
說好的透明狀態(tài)欄呢程腹,怎么狀態(tài)欄背景色是白色的跺涤!



確實是全屏了草慧,狀態(tài)欄也透明了,只是由于要门,根布局沒設置背景色虏肾,默認的背景色白色,所以你看到的灰色狀態(tài)欄底色欢搜,其實是根布局的TopPadding封豪。



8.Activity中嵌套了Fragment,如何使用

另附一張效果圖:


在Activity中設置setStatusBarFullTransparent(),然后在fragment的xml文件中(這邊寫的粗糙炒瘟,應該在代碼中吹埠,獲取StatusBar高度然后設置paddingTop):


有興趣可以可以琢磨一下,為什么這么寫,正所謂:學而不思則罔缘琅,思而不學則殆粘都。

9.問題

這個方案總體來說其實不是很好,會導致過度繪制刷袍,如果對性能要求不是很嚴苛翩隧,可以選擇該方案。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末呻纹,一起剝皮案震驚了整個濱河市堆生,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌雷酪,老刑警劉巖淑仆,帶你破解...
    沈念sama閱讀 207,113評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異哥力,居然都是意外死亡蔗怠,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,644評論 2 381
  • 文/潘曉璐 我一進店門吩跋,熙熙樓的掌柜王于貴愁眉苦臉地迎上來寞射,“玉大人,你說我怎么就攤上這事钞澳〉』蹋” “怎么了?”我有些...
    開封第一講書人閱讀 153,340評論 0 344
  • 文/不壞的土叔 我叫張陵轧粟,是天一觀的道長。 經常有香客問我脓魏,道長兰吟,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,449評論 1 279
  • 正文 為了忘掉前任茂翔,我火速辦了婚禮混蔼,結果婚禮上,老公的妹妹穿的比我還像新娘珊燎。我一直安慰自己惭嚣,他們只是感情好,可當我...
    茶點故事閱讀 64,445評論 5 374
  • 文/花漫 我一把揭開白布悔政。 她就那樣靜靜地躺著晚吞,像睡著了一般。 火紅的嫁衣襯著肌膚如雪谋国。 梳的紋絲不亂的頭發(fā)上槽地,一...
    開封第一講書人閱讀 49,166評論 1 284
  • 那天,我揣著相機與錄音,去河邊找鬼捌蚊。 笑死集畅,一個胖子當著我的面吹牛,可吹牛的內容都是我干的缅糟。 我是一名探鬼主播挺智,決...
    沈念sama閱讀 38,442評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼窗宦!你這毒婦竟也來了逃贝?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 37,105評論 0 261
  • 序言:老撾萬榮一對情侶失蹤迫摔,失蹤者是張志新(化名)和其女友劉穎沐扳,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體句占,經...
    沈念sama閱讀 43,601評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡沪摄,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 36,066評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了纱烘。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片杨拐。...
    茶點故事閱讀 38,161評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖擂啥,靈堂內的尸體忽然破棺而出哄陶,到底是詐尸還是另有隱情,我是刑警寧澤哺壶,帶...
    沈念sama閱讀 33,792評論 4 323
  • 正文 年R本政府宣布屋吨,位于F島的核電站,受9級特大地震影響山宾,放射性物質發(fā)生泄漏至扰。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,351評論 3 307
  • 文/蒙蒙 一资锰、第九天 我趴在偏房一處隱蔽的房頂上張望敢课。 院中可真熱鬧,春花似錦绷杜、人聲如沸直秆。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,352評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽圾结。三九已至,卻和暖如春懊缺,著一層夾襖步出監(jiān)牢的瞬間疫稿,已是汗流浹背培他。 一陣腳步聲響...
    開封第一講書人閱讀 31,584評論 1 261
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留遗座,地道東北人舀凛。 一個月前我還...
    沈念sama閱讀 45,618評論 2 355
  • 正文 我出身青樓,卻偏偏與公主長得像途蒋,于是被迫代替她去往敵國和親猛遍。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 42,916評論 2 344

推薦閱讀更多精彩內容