這里推薦一下鴻洋大神寫的一篇博客Android 沉浸式狀態(tài)欄攻略 讓你的狀態(tài)欄變色吧,文章中寫的很詳細绊谭,可以作為參考癣籽,因此這里只是簡單講述下設置沉浸式狀態(tài)欄的步驟,主要是說一下我在使用過程中碰到的一些問題以及解決方法辨宠。
設置沉浸式狀態(tài)欄
- 如果看過上面推薦的博客就會知道,設置沉浸式狀態(tài)欄通常分為3個步驟(缺一不可)
- 在styles文件中添加
<item name="android:windowTranslucentStatus">true</item>
货裹, - Toolbar布局文件中設置高度為
android:layout_height="wrap_content"
嗤形, - Toolbar布局添加
android:fitsSystemWindows="true"
屬性(注意:如果ToolBar外層還包裹了AppBarLayout布局,則需要將android:fitsSystemWindows="true"
屬性設置在AppBarLayout布局中弧圆。另外如果設置了側(cè)滑菜單赋兵,要將菜單布局也延伸到狀態(tài)欄中的話,同樣需要在菜單布局文件的根布局中設置android:fitsSystemWindows屬性)搔预。
遇到的問題
-
界面中有EditText組件霹期,當EditText獲取焦點彈出軟鍵盤時,ToolBar的布局會延伸拯田,如下圖所示:
當有登錄界面并且登錄界面輸入框較多彈出的軟鍵盤將下面的輸入框擋住時历造,即使將這些輸入框用ScrollView包裹并且在manifest.xml文件中設置了
android:windowSoftInputMode="adjustResize|stateHidden"
時,會有一部分布局依然是被軟鍵盤擋住船庇,無法滑動上來)吭产。-
在開發(fā)中我們通常會遇到實現(xiàn)一些信息錄入的功能,界面布局通常也是最上面是ToolBar鸭轮,最下面是一個保存按鈕(有時也會添加一個取消按鈕臣淤,也有可能是一個Tab組件),中間則是多個信息輸入框窃爷,一般情況下我是比較希望當輸入框獲取焦點彈出軟鍵盤的時候邑蒋,底部的按鈕一同被頂上來姓蜂,比如說像下圖這樣(中間的輸入框是用ScrollView包裹起來的)
而實際情況是,當我們按照上面設置的步驟只要在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>
這兩個屬性引起的享钞,因此對應的解決方案主要是針對他們的揍诽。
- 上面的第一個問題也就是輸入框獲取焦點軟鍵盤彈出時ToolBar布局出現(xiàn)延伸的問題,這個問題是由于對ToolBar布局設置了
android:fitsSystemWindows="true"
栗竖。 - 上面的第二個和第三個問題是因為我們在styles文件中設置了
<item name="android:windowTranslucentStatus">true</item>
這個屬性引起的暑脆。我在使用的時候發(fā)現(xiàn)只要設置了這個屬性,界面布局簡短的時候還好狐肢,當界面布局比較長以以至于有一部分被彈出的軟件盤遮住的時候添吗,不管我使用什么辦法,都無法將被遮住的布局滑上來(貌似使用列表組件可以份名,但是我沒試過碟联,而且列表組件限制比較大,比如說界面輸入是用Fragment實現(xiàn)的)僵腺。
解決方法
- 最佳的解決方法就是不用沉浸式鲤孵,畢竟現(xiàn)在手機都是5.0以上的,可以直接設置狀態(tài)欄的藍色辰如,我們可以直接在項目中設置最低版本為api21版本普监。
- 針對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);
}
}
- 這樣便解決了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)用在了自己的項目上面,在此感謝該開源庫作者的辛勤維護败明。