首先說一下我對沉浸式狀态欄的了解,在4.4之前,狀态欄都是黑乎乎的,看起來很不美觀,在4.4之後可以将狀态欄設定成透明并和标題欄同一種顔色。以下是我總結的實作沉浸式的幾種方式。
第一種方式:使用系統API實作沉浸式
1.1、首先看布局檔案
添加android:fitsSystemWindows=”true”, android:clipToPadding=”true”兩個屬性
<?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"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="teststatusbar.com.xn.teststatusbar.MainActivity">
<TextView
android:background="@android:color/holo_blue_dark"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clipToPadding="true"
android:fitsSystemWindows="true"
android:onClick="firstWay"
android:text="第一種方式實作沉浸式狀态欄" />
</LinearLayout>
或者直接設定屬性:
<item name="android:statusBarColor">@color/system_bottom_nav_color</item>,
這個屬性是直接設定狀态欄的顔色,這個屬性是在style中設定的。或者直接用代碼來改變顔色,隻在5.0及以上才能起作用。
<item name="android:windowTranslucentStatus">true</item>
這個屬性就是設定狀态欄為透明,同樣在style檔案中來設定的,但是有個弊端就是狀态欄會往上移,是以标題欄的高度會減少,減少的高度為狀态欄的高度,大概是24dp。這時我們通過反射機制來動态增加高度,或者給Toolbar設定android:fitsSystemWindows=”true”,或者給最外層的容器設定這個屬性,這樣也可以将減少的高度補回來。
1.2、java代碼如下:
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initStatusbar();
}
/**
* 初始化狀态欄
*/
private void initStatusbar() {
//這裡是判斷目前的目标版本是否在4.4及以上,如果在4.4之上我們才設定沉浸式
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
//透明狀态欄
getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
//透明導航欄
getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
}
}
}
效果如下:
![](https://img.laitimes.com/img/__Qf2AjLwojIjJCLyojI0JCLiQ3chVEa0V3bT9CX5RXa2Fmcn9CXwczLcVmds92czlGZvwVP9EUTDZ0aRJkSwk0LcxGbpZ2LcBDM08CXlpXazRnbvZ2LcRlMMVDT2EWNvwFdu9mZvwVPFRkTwsGVOhXV61kZShVW1xmMjZXUYpVd1kmYr50MZV3YyI2cKJDT29GRjBjUIF2LcRHelR3LcJzLctmch1mclRXY39DN3UDN0czMxEzNwgDM3EDMy8CX0Vmbu4GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.jpg)
第二種方式:使用反射機制動态加載标題欄
思路是這樣的:先擷取到狀态欄的高度,再擷取到我們自定義的标題欄的高度,然後将我們的标題欄的高度設定為兩者之和,在這之前需要将我們原本的狀态欄設為透明。這樣就完成了我們的沉浸式狀态欄。
2.1:在布局檔案中定義好自定義的标題欄
<?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"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="teststatusbar.com.xn.teststatusbar.SecondActivity">
<LinearLayout
android:id="@+id/line"
android:layout_width="match_parent"
android:layout_height="80dp"
android:background="@android:color/holo_blue_dark">
<TextView
android:layout_gravity="center"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="第二種方式實作沉浸式狀态欄" />
</LinearLayout>
</LinearLayout>
高度我們設定的80dp。
2.2、在java代碼中動态設定狀态欄的高度
public class SecondActivity extends AppCompatActivity {
LinearLayout lin;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_second);
lin = (LinearLayout) findViewById(R.id.line);
setStatus();
}
/**
* 設定沉浸式狀态欄
*/
private void setStatus() {
//判斷是否是大于目前版本4.4,如果大于則實作沉浸式
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
//标題欄透明
getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
//導航欄透明
getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
lin.post(new Runnable() {
@Override
public void run() {
final int statusheight = getLayoutHeight();
final int linHeight = lin.getHeight();
Log.e("statusheight linHeight", ""+statusheight+":"+linHeight);
ViewGroup.LayoutParams layoutParams = lin.getLayoutParams();
layoutParams.height = statusheight + linHeight;
lin.setLayoutParams(layoutParams);
}
});
}
}
/**
* 擷取狀态欄的高度
*
* @return
*/
public int getLayoutHeight() {
try {
Class<?> clazz = Class.forName("com.android.internal.R$dimen");
Object obj = clazz.newInstance();
Field field = clazz.getField("status_bar_height");
int height = Integer.parseInt(field.get(obj).toString());
return getResources().getDimensionPixelSize(height);
} catch (Exception e) {
e.printStackTrace();
}
return ;
}
}
這裡需要注意的是,擷取我們自定義的狀态欄的高度設定參數的代碼,我們是放在view.post(new Runnable…)中的,為什麼要放在這裡面而不直接寫呢,如果直接在onCreate方法裡面擷取一個view的參數如寬高等,是擷取不到的,一直會是0,因為在onCreate方法中,也許view還沒執行測量方法。
那為什麼放在post方法中就能擷取到了呢?這裡是将Runnable添加到消息隊列中,保證在UI線程中執行,這裡就能保證在View繪制完成之後擷取到寬高,就能取到值了。
最終的執行效果如下:
第三種方式:使用Toolbar自動帶有沉浸式的效果
Toolbar的具體使用方式詳見:http://blog.csdn.net/sinat_35159441/article/details/76794117
其實本質就是5.0自動實作了沉浸式的效果,通過主題的設定來改變狀态欄的顔色。colorPrimaryDark這個屬性就是用來顯示狀态欄的顔色的。
<style name="AppTheme" parent="AppBaseTheme">
<!-- All customizations that are NOT specific to a particular API-level can go here. -->
<item name="android:textColor">@color/mytextcolor</item>
<item name="colorPrimary">@color/colorPrimary_pink</item>
<item name="colorPrimaryDark">@color/colorPrimary_pinkDark</item>