沉浸式狀態(tài)欄工具類

沉浸式狀態(tài)欄的實(shí)現(xiàn)原理很簡(jiǎn)單,就是將狀態(tài)欄隱藏掉坷随,然后在原來(lái)狀態(tài)欄的位置添加一個(gè)和狀態(tài)欄大小一模一樣的View洽损,這個(gè)View的顏色定義成和Toolbar一樣的顏色就行了

在styles.xml文件中設(shè)置主題樣式為NoActionBar

    <!-- Base application theme. -->
    <style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
        <!-- Customize your theme here. -->
        <item name="colorPrimary">@color/colorPrimary</item>
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
        <item name="colorAccent">@color/colorAccent</item>
    </style>

這樣系統(tǒng)自帶的ActionBar就沒(méi)有了本辐,需要自己在布局文件中添加Toolbar

透明化狀態(tài)欄

/**
 * 沉浸式狀態(tài)欄工具類
 */
public class StatusBarUtils {

    /**
     * 透明化狀態(tài)欄
     */
    public static void transparentStatusBar(Activity act, boolean fitWindow) {
        Window window = act.getWindow();

        //透明狀態(tài)欄
        window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);

        //獲取根布局
        ViewGroup root = (ViewGroup) act.findViewById(android.R.id.content);
        View firstChild = root.getChildAt(0);
        if (firstChild != null) {
            //設(shè)置root的第一個(gè)子View赏酥,使其為系統(tǒng)View預(yù)留空間.
            firstChild.setFitsSystemWindows(fitWindow);
        }
    }

}
window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);

這行代碼的作用就是使?fàn)顟B(tài)欄透明化

        //獲取根布局
        ViewGroup root = (ViewGroup) act.findViewById(android.R.id.content);
        View firstChild = root.getChildAt(0);
        if (firstChild != null) {
            //設(shè)置root的第一個(gè)子View,使其為系統(tǒng)View預(yù)留空間.
            firstChild.setFitsSystemWindows(fitWindow);
        }

這一串代碼的作用是就是在布局文件的最外層控件上添加了一個(gè)android:fitsSystemWindows="true"屬性管搪,當(dāng)然也可以在布局文件中添加虾攻,就像下面這樣

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true"
    android:orientation="vertical">

    <android.support.v7.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"
        android:background="@color/blue"
        app:title="標(biāo)題"/>

</LinearLayout>

android:fitsSystemWindows="true"的效果是為系統(tǒng)View預(yù)留空間,也就是將狀態(tài)欄的位置空出來(lái)更鲁,它的默認(rèn)值是false霎箍。下圖是對(duì)比這個(gè)屬性在狀態(tài)欄透明時(shí)設(shè)置為true和false的區(qū)別

設(shè)置為true的效果

設(shè)置為false的效果

創(chuàng)建狀態(tài)欄

public static View createStatusBar(Context context, int color) {

        //方法原理:
        //添加一個(gè)和狀態(tài)欄高、寬相同的指定顏色的View來(lái)覆蓋被透明化的狀態(tài)欄
        View statusBar = new View(context);
        LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
                ViewGroup.LayoutParams.MATCH_PARENT, getStatusBarHeight(context));

        statusBar.setLayoutParams(params);
        statusBar.setBackgroundColor(color);

        return statusBar;
    }

這部分沒(méi)什么好講的澡为,就是單純的創(chuàng)建一個(gè)狀態(tài)欄漂坏,狀態(tài)欄的顏色通過(guò)參數(shù)設(shè)置

public static int getStatusBarHeight(Context context) {
        int statusBarHeight = -1;

        try {
            Class clazz = Class.forName("com.android.internal.R$dimen");
            //通過(guò)反射獲取狀態(tài)欄高度這個(gè)成員變量
            Field status_bar_height = clazz.getField("status_bar_height");

            Object obj = clazz.newInstance();
            int height = Integer.parseInt(status_bar_height.get(obj).toString());
            statusBarHeight = context.getResources().getDimensionPixelSize(height);
        } catch (Exception e) {
            e.printStackTrace();
        }

        return statusBarHeight;
    }

這個(gè)方法用于獲取狀態(tài)欄的高度,不用在意方法的實(shí)現(xiàn)細(xì)節(jié)媒至,只需要知道這個(gè)方法能夠獲取到狀態(tài)欄的高度就行了

將創(chuàng)建的狀態(tài)欄添加到布局上

    public static void addStatusBar(Activity act, int color) {
        int resource = act.getResources().getColor(color);
        //創(chuàng)建狀態(tài)欄
        View statusBar = createStatusBar(act, resource);

        //獲取根布局
        ViewGroup root = (ViewGroup) act.findViewById(android.R.id.content);
        //將狀態(tài)欄添加到根布局的第一個(gè)子布局位置
        root.addView(statusBar, 0);
    }

這個(gè)方法的第二個(gè)參數(shù)是傳入顏色的id顶别,例如R.color.colorPrimary這樣的參數(shù)。
這個(gè)方法的作用是將狀態(tài)欄添加到布局上去拒啰,什么意思驯绎?畫個(gè)圖解釋

布局

root.addView(statusBar, 0);這行代碼就是將狀態(tài)欄添加到根布局下面,參數(shù)0代表位置
需要注意的是根布局不是指布局文件中最外層的控件

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true"
    android:orientation="vertical">

    <android.support.v7.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"
        android:background="@color/blue"
        app:title="標(biāo)題"/>

</LinearLayout>

我的布局文件是這樣的谋旦,根布局并不是指LinearLayout

最后一步

    /**
     * 繪制狀態(tài)欄
     * @param act
     * @param color
     */
    public static void drawableStatusBar(Activity act, int color) {
        transparentStatusBar(act, true);
        addStatusBar(act, color);
    }

添加上這個(gè)方法工具類就完成了剩失,下面是完整的代碼

/**
 * 沉浸式狀態(tài)欄工具類
 */
public class StatusBarUtils {

    /**
     * 繪制狀態(tài)欄
     * @param act
     * @param color
     */
    public static void drawableStatusBar(Activity act, int color) {
        transparentStatusBar(act, true);
        addStatusBar(act, color);
    }

    /**
     * 透明化狀態(tài)欄
     *
     * @param act
     */
    public static void transparentStatusBar(Activity act, boolean fitWindow) {
        Window window = act.getWindow();

        //透明狀態(tài)欄
        window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
        //透明導(dǎo)航欄
        window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);

        //獲取根布局
        ViewGroup root = (ViewGroup) act.findViewById(android.R.id.content);
        View firstChild = root.getChildAt(0);
        if (firstChild != null) {
            //設(shè)置 root 的第一個(gè)子 View . 使其為系統(tǒng) View 預(yù)留空間.
            firstChild.setFitsSystemWindows(fitWindow);
        }
    }

    /**
     * 添加狀態(tài)欄
     *
     * @param act
     * @param color
     */
    public static void addStatusBar(Activity act, int color) {
        int resource = act.getResources().getColor(color);
        //創(chuàng)建狀態(tài)欄
        View statusBar = createStatusBar(act, resource);

        //獲取根布局
        ViewGroup root = (ViewGroup) act.findViewById(android.R.id.content);
        //將狀態(tài)欄添加到根布局下的第一個(gè)子布局位置
        root.addView(statusBar, 0);
    }

    /**
     * 創(chuàng)建一個(gè)狀態(tài)欄
     *
     * @param context
     * @param color
     * @return
     */
    public static View createStatusBar(Context context, int color) {

        //方法原理:
        //添加一個(gè)和狀態(tài)欄高屈尼、寬相同的指定顏色的View來(lái)覆蓋被透明化的狀態(tài)欄
        View statusBar = new View(context);
        LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
                ViewGroup.LayoutParams.MATCH_PARENT, getStatusBarHeight(context));

        statusBar.setLayoutParams(params);
        statusBar.setBackgroundColor(color);

        return statusBar;
    }

    /**
     * 獲取狀態(tài)欄高度
     *
     * @param context
     * @return
     */
    public static int getStatusBarHeight(Context context) {
        int statusBarHeight = -1;

        try {
            Class clazz = Class.forName("com.android.internal.R$dimen");
            //通過(guò)反射獲取狀態(tài)欄高度這個(gè)成員變量
            Field status_bar_height = clazz.getField("status_bar_height");

            Object obj = clazz.newInstance();
            int height = Integer.parseInt(status_bar_height.get(obj).toString());
            statusBarHeight = context.getResources().getDimensionPixelSize(height);
        } catch (Exception e) {
            e.printStackTrace();
        }

        return statusBarHeight;
    }

}

onCreate()方法中調(diào)用

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        StatusBarUtils.drawableStatusBar(this, R.color.colorPrimary);
    }

效果如下


沉浸式狀態(tài)欄
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市拴孤,隨后出現(xiàn)的幾起案子脾歧,更是在濱河造成了極大的恐慌,老刑警劉巖乞巧,帶你破解...
    沈念sama閱讀 218,941評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件涨椒,死亡現(xiàn)場(chǎng)離奇詭異摊鸡,居然都是意外死亡绽媒,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,397評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門免猾,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)是辕,“玉大人,你說(shuō)我怎么就攤上這事猎提』袢” “怎么了?”我有些...
    開(kāi)封第一講書人閱讀 165,345評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵锨苏,是天一觀的道長(zhǎng)疙教。 經(jīng)常有香客問(wèn)我,道長(zhǎng)伞租,這世上最難降的妖魔是什么贞谓? 我笑而不...
    開(kāi)封第一講書人閱讀 58,851評(píng)論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮葵诈,結(jié)果婚禮上裸弦,老公的妹妹穿的比我還像新娘。我一直安慰自己作喘,他們只是感情好理疙,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,868評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著泞坦,像睡著了一般窖贤。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上贰锁,一...
    開(kāi)封第一講書人閱讀 51,688評(píng)論 1 305
  • 那天赃梧,我揣著相機(jī)與錄音,去河邊找鬼李根。 笑死槽奕,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的房轿。 我是一名探鬼主播粤攒,決...
    沈念sama閱讀 40,414評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼所森,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了夯接?” 一聲冷哼從身側(cè)響起焕济,我...
    開(kāi)封第一講書人閱讀 39,319評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎盔几,沒(méi)想到半個(gè)月后晴弃,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,775評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡逊拍,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,945評(píng)論 3 336
  • 正文 我和宋清朗相戀三年上鞠,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片芯丧。...
    茶點(diǎn)故事閱讀 40,096評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡芍阎,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出缨恒,到底是詐尸還是另有隱情谴咸,我是刑警寧澤,帶...
    沈念sama閱讀 35,789評(píng)論 5 346
  • 正文 年R本政府宣布骗露,位于F島的核電站岭佳,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏萧锉。R本人自食惡果不足惜珊随,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,437評(píng)論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望驹暑。 院中可真熱鬧玫恳,春花似錦、人聲如沸优俘。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 31,993評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)帆焕。三九已至惭婿,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間叶雹,已是汗流浹背财饥。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 33,107評(píng)論 1 271
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留折晦,地道東北人钥星。 一個(gè)月前我還...
    沈念sama閱讀 48,308評(píng)論 3 372
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像满着,于是被迫代替她去往敵國(guó)和親谦炒。 傳聞我的和親對(duì)象是個(gè)殘疾皇子贯莺,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,037評(píng)論 2 355

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