Android為ToolBar設置沉浸式狀態(tài)欄及其相關問題處理

這里推薦一下鴻洋大神寫的一篇博客Android 沉浸式狀態(tài)欄攻略 讓你的狀態(tài)欄變色吧,文章中寫的很詳細绊谭,可以作為參考癣籽,因此這里只是簡單講述下設置沉浸式狀態(tài)欄的步驟,主要是說一下我在使用過程中碰到的一些問題以及解決方法辨宠。

設置沉浸式狀態(tài)欄

  • 如果看過上面推薦的博客就會知道,設置沉浸式狀態(tài)欄通常分為3個步驟(缺一不可)
  1. 在styles文件中添加<item name="android:windowTranslucentStatus">true</item>货裹,
  2. Toolbar布局文件中設置高度為android:layout_height="wrap_content"嗤形,
  3. Toolbar布局添加android:fitsSystemWindows="true"屬性(注意:如果ToolBar外層還包裹了AppBarLayout布局,則需要將android:fitsSystemWindows="true"屬性設置在AppBarLayout布局中弧圆。另外如果設置了側(cè)滑菜單赋兵,要將菜單布局也延伸到狀態(tài)欄中的話,同樣需要在菜單布局文件的根布局中設置android:fitsSystemWindows屬性)搔预。

遇到的問題

  1. 界面中有EditText組件霹期,當EditText獲取焦點彈出軟鍵盤時,ToolBar的布局會延伸拯田,如下圖所示:


    image.png
  2. 當有登錄界面并且登錄界面輸入框較多彈出的軟鍵盤將下面的輸入框擋住時历造,即使將這些輸入框用ScrollView包裹并且在manifest.xml文件中設置了android:windowSoftInputMode="adjustResize|stateHidden"時,會有一部分布局依然是被軟鍵盤擋住船庇,無法滑動上來)吭产。

  3. 在開發(fā)中我們通常會遇到實現(xiàn)一些信息錄入的功能,界面布局通常也是最上面是ToolBar鸭轮,最下面是一個保存按鈕(有時也會添加一個取消按鈕臣淤,也有可能是一個Tab組件),中間則是多個信息輸入框窃爷,一般情況下我是比較希望當輸入框獲取焦點彈出軟鍵盤的時候邑蒋,底部的按鈕一同被頂上來姓蜂,比如說像下圖這樣(中間的輸入框是用ScrollView包裹起來的)

    image.png

    而實際情況是,當我們按照上面設置的步驟只要在styles文件中設置了
    <item name="android:windowTranslucentStatus">true</item>這個屬性就會發(fā)現(xiàn)當輸入組件獲取焦點軟件盤彈出時医吊,底部的按鈕是不會被頂上來的钱慢,這個就有點坑爹了。雖然沒什么大的影響卿堂,但作為有強迫癥的我是不允許出現(xiàn)這種情況的滩字。

  • 好了基本上我在使用沉浸式狀態(tài)欄過程中碰到的一些問題都列在上面了,可能還有別的問題沒有碰到御吞,這個以后再說。

問題原因及解決方法

這里參考了一篇博客談談“adjustResize”在沉浸式狀態(tài)欄下的失效問題漓藕,該博客完美的解決了上面所說的問題陶珠,我就直接將其中的一些內(nèi)容照抄過來了。

問題原因
  • 其實大部分問題都是由android:fitsSystemWindows="true"<item name="android:windowTranslucentStatus">true</item>這兩個屬性引起的享钞,因此對應的解決方案主要是針對他們的揍诽。
  1. 上面的第一個問題也就是輸入框獲取焦點軟鍵盤彈出時ToolBar布局出現(xiàn)延伸的問題,這個問題是由于對ToolBar布局設置了android:fitsSystemWindows="true"栗竖。
  2. 上面的第二個和第三個問題是因為我們在styles文件中設置了<item name="android:windowTranslucentStatus">true</item>這個屬性引起的暑脆。我在使用的時候發(fā)現(xiàn)只要設置了這個屬性,界面布局簡短的時候還好狐肢,當界面布局比較長以以至于有一部分被彈出的軟件盤遮住的時候添吗,不管我使用什么辦法,都無法將被遮住的布局滑上來(貌似使用列表組件可以份名,但是我沒試過碟联,而且列表組件限制比較大,比如說界面輸入是用Fragment實現(xiàn)的)僵腺。
解決方法
  1. 最佳的解決方法就是不用沉浸式鲤孵,畢竟現(xiàn)在手機都是5.0以上的,可以直接設置狀態(tài)欄的藍色辰如,我們可以直接在項目中設置最低版本為api21版本普监。
  2. 針對ToolBar布局延伸,參照上面引用博客琉兜,我們自定義布局凯正,將ToolBar包裹進去,并將android:fitsSystemWindows="true"屬性設置在自定義的布局里面呕童,同時ToolBar的背景顏色也到移動到自定的布局里面漆际,否則狀態(tài)欄不會顯示我們設置好的顏色,代碼如下:
        <com.mobile.library.view.ImmerseGroup
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="@color/colorPrimary"
            android:fitsSystemWindows="true">
            <android.support.v7.widget.Toolbar
                android:id="@+id/main_toolbar"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:minHeight="?actionBarSize"
                app:popupTheme="@style/PopupOverlay"
                app:theme="@style/AppBarOverlay">
           </android.support.v7.widget.Toolbar>
        </com.mobile.library.view.ImmerseGroup>

該自定義布局代碼如下:

        import android.content.Context;
        import android.support.annotation.Nullable;
        import android.util.AttributeSet;
        import android.widget.FrameLayout;

        /**
         * 沉浸式狀態(tài)欄Toolbar輔助類
         * 避免Toolbar設置fitSystemWindows="true"當軟鍵盤彈出時Toolbar被拉伸
         */ 
        public class ImmerseGroup extends FrameLayout {
            public ImmerseGroup(Context context) {
                super(context);
            }
            public ImmerseGroup(Context context, @Nullable AttributeSet attrs) {
                super(context, attrs);
            }
            public ImmerseGroup(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
                super(context, attrs, defStyleAttr);
            }
            @Override
            protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
                setPadding(getPaddingLeft(), getPaddingTop(), getPaddingRight(), 0);
                super.onMeasure(widthMeasureSpec, heightMeasureSpec);
            }
        }
  1. 這樣便解決了ToolBar布局延伸的問題夺饲,但是另外一個問題還沒有解決奸汇,就是底部的組件如何才能被軟鍵盤頂上來施符,這里采用了一個工具類來監(jiān)聽android.R.id.content的布局,在軟鍵盤彈出時擂找,動態(tài)改變其高度戳吝,為軟鍵盤騰出空間。該工具類代碼如下:
        import android.graphics.Rect;
        import android.view.View;
        import android.view.ViewGroup;
        import android.view.ViewTreeObserver;

        public class AndroidBug5497Workaround {
            public static void assistActivity(View content) {
                new AndroidBug5497Workaround(content);
            }

            private View mChildOfContent;
            private int usableHeightPrevious;
            private ViewGroup.LayoutParams frameLayoutParams;

            private AndroidBug5497Workaround(View content) {
                if (content != null) {
                    mChildOfContent = content;
                    mChildOfContent.getViewTreeObserver().addOnGlobalLayoutListener(
                        new ViewTreeObserver.OnGlobalLayoutListener() {
                            public void onGlobalLayout() {
                                possiblyResizeChildOfContent();
                        }
                    });
                    frameLayoutParams = mChildOfContent.getLayoutParams();
                }
            }
            private void possiblyResizeChildOfContent() {
                int usableHeightNow = computeUsableHeight();
                if (usableHeightNow != usableHeightPrevious) {
                    frameLayoutParams.height = usableHeightNow;
                    mChildOfContent.requestLayout();
                    usableHeightPrevious = usableHeightNow;
                }
            }
            private int computeUsableHeight() {
                Rect r = new Rect();
                mChildOfContent.getWindowVisibleDisplayFrame(r);
                return (r.bottom);
            }
        }

然后在需要設置的Activity中添加下面一行代碼就可以了:
AndroidBug5497Workaround.assistActivity(findViewById(android.R.id.content));

題外話

  • 有時候我們嫌沉浸式布局比較麻煩贯涎,不想使用听哭,但又想在5.0以下的手機上設置狀態(tài)欄的顏色,這里安利一個GitHub上面的開源庫msdx/status-bar-compat塘雳,其實現(xiàn)的狀態(tài)欄效果和沉浸式狀態(tài)欄幾乎一樣(布局并沒有延伸到狀態(tài)欄上面)陆盘,我已經(jīng)用在了自己的項目上面,在此感謝該開源庫作者的辛勤維護败明。
最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末隘马,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子妻顶,更是在濱河造成了極大的恐慌酸员,老刑警劉巖,帶你破解...
    沈念sama閱讀 212,383評論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件讳嘱,死亡現(xiàn)場離奇詭異幔嗦,居然都是意外死亡,警方通過查閱死者的電腦和手機沥潭,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,522評論 3 385
  • 文/潘曉璐 我一進店門邀泉,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人钝鸽,你說我怎么就攤上這事呼渣。” “怎么了寞埠?”我有些...
    開封第一講書人閱讀 157,852評論 0 348
  • 文/不壞的土叔 我叫張陵屁置,是天一觀的道長。 經(jīng)常有香客問我仁连,道長蓝角,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,621評論 1 284
  • 正文 為了忘掉前任饭冬,我火速辦了婚禮使鹅,結果婚禮上,老公的妹妹穿的比我還像新娘昌抠。我一直安慰自己患朱,他們只是感情好,可當我...
    茶點故事閱讀 65,741評論 6 386
  • 文/花漫 我一把揭開白布炊苫。 她就那樣靜靜地躺著裁厅,像睡著了一般冰沙。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上执虹,一...
    開封第一講書人閱讀 49,929評論 1 290
  • 那天拓挥,我揣著相機與錄音,去河邊找鬼袋励。 笑死侥啤,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的茬故。 我是一名探鬼主播盖灸,決...
    沈念sama閱讀 39,076評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼磺芭!你這毒婦竟也來了糠雨?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,803評論 0 268
  • 序言:老撾萬榮一對情侶失蹤徘跪,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后琅攘,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體垮庐,經(jīng)...
    沈念sama閱讀 44,265評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,582評論 2 327
  • 正文 我和宋清朗相戀三年坞琴,在試婚紗的時候發(fā)現(xiàn)自己被綠了哨查。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,716評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡剧辐,死狀恐怖寒亥,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情荧关,我是刑警寧澤溉奕,帶...
    沈念sama閱讀 34,395評論 4 333
  • 正文 年R本政府宣布,位于F島的核電站忍啤,受9級特大地震影響加勤,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜同波,卻給世界環(huán)境...
    茶點故事閱讀 40,039評論 3 316
  • 文/蒙蒙 一鳄梅、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧未檩,春花似錦戴尸、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,798評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽项棠。三九已至,卻和暖如春马篮,著一層夾襖步出監(jiān)牢的瞬間沾乘,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,027評論 1 266
  • 我被黑心中介騙來泰國打工浑测, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留翅阵,地道東北人。 一個月前我還...
    沈念sama閱讀 46,488評論 2 361
  • 正文 我出身青樓迁央,卻偏偏與公主長得像掷匠,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子岖圈,可洞房花燭夜當晚...
    茶點故事閱讀 43,612評論 2 350