如何實(shí)現(xiàn)沉浸式狀態(tài)欄

前段時間項(xiàng)目中需要實(shí)現(xiàn)一個這樣的功能,也是具體去研究了一下,趁著最近不是很忙,所以就整理了一個工具類XStatusBarHelper,也在這兒分享一下自己的實(shí)現(xiàn)方式。

何為沉浸式狀態(tài)欄

簡單的來說,就是狀態(tài)欄可以改變顏色,不再是默認(rèn)的黑色?;蛘郀顟B(tài)欄是透明的,內(nèi)容在狀態(tài)欄下面。當(dāng)然很多人也說這樣不叫沉浸式狀態(tài)欄,這個就不去深入研究了,先來看看我們最終想要的效果。

效果一:狀態(tài)欄變色
效果二:狀態(tài)欄透明全屏

如何實(shí)現(xiàn)

首先只有Android版本大于等于4.4才能夠?qū)崿F(xiàn)這樣的效果,并且在4.4和5.0的上可以有不同的方式實(shí)現(xiàn),這里我就講一講我是如何實(shí)現(xiàn)的。

效果一:狀態(tài)欄變色

大致的思路就是設(shè)置狀態(tài)欄透明,然后為根ViewGroup添加一個與狀態(tài)欄相同高度的View,設(shè)置其顏色。

    /**
 * Android4.4以上的狀態(tài)欄著色
 *
 * @param window         一般都是用于Activity的window,也可以是其他的例如Dialog,DialogFragment
 * @param statusBarColor 狀態(tài)欄顏色
 * @param alpha          透明欄透明度[0.0-1.0]
 */
public static void tintStatusBar(Window window, @ColorInt int statusBarColor, @FloatRange(from = 0.0, to = 1.0)
        float alpha) {
    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {
        return;
    }

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
        window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
        window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
        window.setStatusBarColor(Color.TRANSPARENT);
    } else {
        window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
    }

    ViewGroup decorView = (ViewGroup) window.getDecorView();
    ViewGroup contentView = (ViewGroup) window.getDecorView().findViewById(Window.ID_ANDROID_CONTENT);
    View rootView = contentView.getChildAt(0);
    if (rootView != null) {
        //設(shè)置為true后,布局會自動加上狀態(tài)欄高度的距離
        ViewCompat.setFitsSystemWindows(rootView, true);
    }
    //設(shè)置一個狀態(tài)欄
    setStatusBar(decorView, statusBarColor, true);
    //設(shè)置一個半透明效果,Material Design的效果
    setTranslucentView(decorView, alpha);
}

/**
 * 創(chuàng)建假的狀態(tài)欄View
 */
private static void setStatusBar(ViewGroup container, @ColorInt int statusBarColor, boolean visible, boolean
        addToFirst) {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
        View statusBarView = container.findViewById(R.id.statusbar_view);
        if (statusBarView == null) {
            statusBarView = new View(container.getContext());
            statusBarView.setId(R.id.statusbar_view);
            ViewGroup.LayoutParams lp = new ViewGroup.LayoutParams(
                    ViewGroup.LayoutParams.MATCH_PARENT, getStatusBarHeight(container.getContext()));
            if (addToFirst) {
                container.addView(statusBarView, 0, lp);
            } else {
                container.addView(statusBarView, lp);
            }
        }

        statusBarView.setBackgroundColor(statusBarColor);
        statusBarView.setVisibility(visible ? View.VISIBLE : View.GONE);
    }
}

效果二:全屏狀態(tài)欄透明

/**
 * Android4.4以上的沉浸式全屏模式
 * <p>
 * 注:
 * 1.刪除fitsSystemWindows屬性:Android5.0以上使用該方法如果出現(xiàn)界面展示不正確,刪除布局中所有fitsSystemWindows屬性
 * 或者調(diào)用forceFitsSystemWindows方法
 * 2.不刪除fitsSystemWindows屬性:也可以區(qū)別處理,Android5.0以上使用自己的方式實(shí)現(xiàn),不調(diào)用該方法
 *
 * @param window 一般都是用于Activity的window,也可以是其他的例如Dialog,DialogFragment
 * @param alpha  透明欄透明度[0.0-1.0]
 */
public static void immersiveStatusBar(Window window, @FloatRange(from = 0.0, to = 1.0) float alpha) {
    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {
        return;
    }

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
        window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
        window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
        window.setStatusBarColor(Color.TRANSPARENT);

        int systemUiVisibility = window.getDecorView().getSystemUiVisibility();
        systemUiVisibility |= View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN;
        systemUiVisibility |= View.SYSTEM_UI_FLAG_LAYOUT_STABLE;
        window.getDecorView().setSystemUiVisibility(systemUiVisibility);
    } else {
        window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
    }

    ViewGroup decorView = (ViewGroup) window.getDecorView();
    ViewGroup contentView = (ViewGroup) window.getDecorView().findViewById(Window.ID_ANDROID_CONTENT);
    View rootView = contentView.getChildAt(0);
    int statusBarHeight = getStatusBarHeight(window.getContext());
    if (rootView != null) {
        FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) rootView.getLayoutParams();
        ViewCompat.setFitsSystemWindows(rootView, true);
        lp.topMargin = -statusBarHeight;
        rootView.setLayoutParams(lp);
    }

    setTranslucentView(decorView, alpha);
}

詳細(xì)的代碼太多了,這里就不全部貼出來了,全部代碼可到這兒查看XStatusBarHelper:https://github.com/fodroid/XStatusBarHelper

XStatusBarHelper使用

使用效果圖

?快速集成

gradle

Add it in your root build.gradle at the end of repositories:

allprojects {
    repositories {
        ...
        maven { url 'https://jitpack.io' }
    }
}

Add the dependency

dependencies {
    compile 'com.github.fodroid:XStatusBarHelper:v1.1'
}

maven

<repositories>
    <repository>
        <id>jitpack.io</id>
        <url>https://jitpack.io</url>
    </repository>
</repositories>

<dependency>
    <groupId>com.github.fodroid</groupId>
    <artifactId>XStatusBarHelper</artifactId>
    <version>v1.1</version>
</dependency>

具體調(diào)用代碼

包含DrawerLayout

XStatusBarHelper.tintStatusBarForDrawer(this, drawer, getResources().getColor(R.color.colorPrimary));

效果一

XStatusBarHelper.tintStatusBar(this, getResources().getColor(R.color.colorPrimary));
//或者采用以下方式
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
XStatusBarHelper.forceFitsSystemWindows(this);
XStatusBarHelper.immersiveStatusBar(this);
XStatusBarHelper.setHeightAndPadding(this, toolbar);

效果二

Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
XStatusBarHelper.forceFitsSystemWindows(this);
XStatusBarHelper.immersiveStatusBar(this);
XStatusBarHelper.setHeightAndPadding(this, toolbar);

詳細(xì)的調(diào)用方式,可以查看Github上面的例子:XStatusBarHelper

如果你覺得有用,請在Github不吝給我一個Star,非常感謝。


寫在最后的話:個人能力有限,歡迎大家在下面吐槽。喜歡的話就為我點(diǎn)一個贊吧。也歡迎 Fork Me On Github 。

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

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

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 178,753評論 25 709
  • 今日去市里開人才新政會議,午休有時間,還去感受了下臺州人力網(wǎng)的14周年會現(xiàn)場。二個會議,有個共同的東西讓我深深...
    無憂俠閱讀 147評論 0 0
  • 本文源自 Salman Khan 對 Elon Musk 四年前的一次 Chat,也是 Khan Academy ...
    馬文Marvin閱讀 1,513評論 2 0
  • 這幾天已經(jīng)慢慢習(xí)慣早上一起床就aom,然后就是聲音練習(xí),從無聲到有聲,無聲包括發(fā)si音、長短交替si音、狗喘氣、打...
    云淡風(fēng)輕一閱讀 111評論 0 0
  • 今天,我和楠哥又吵架了。 其實(shí)不是什么大不了的事情,只是因?yàn)樗谕鎯河螒?,而我想他陪我出去晃蕩?好難過啊,感覺楠...
    熊師娘閱讀 385評論 8 12

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