Android使用fitsSystemWindows屬性實現–狀態欄【status_bar】各版本適配方案

Android使用fitsSystemWindows屬性實現–狀態欄【status_bar】各版本適配方案 
首先我們看下qq的status bar在各個android版本系統中適配:

1.Android5.0以上:半透明(APP 的內容不被上拉到狀態) 
這裏寫圖片描述

2.Android4.4以上:全透明(APP 的內容不被上拉到狀態) 
這裏寫圖片描述

3.Android4.4以下:不佔據status bar 
這裏寫圖片描述

這裏我們就按照qq在各個android的版本顯示進行適配: 
1.Android5.0以上:material design風格,半透明(APP 的內容不被上拉到狀態) 
2.Android4.4(kitkat)以上至5.0:全透明(APP 的內容不被上拉到狀態) 
3.Android4.4(kitkat)以下:不佔據status bar

主題: 
使用Theme.AppCompat.Light.NoActionBar(toolbar的兼容主題):既可以適配使用toolbar(由於google已經不再建議使用action bar了,而是推薦使用toolbar,且toolbar的使用更加的靈活,所以toolbar和actionbar的選擇也沒什麼好糾結的)和不使用toolbar的情況(即自定義topBar佈局)。

fitSystemWindows屬性: 
官方描述: 
Boolean internal attribute to adjust view layout based on system windows such as the status bar. If true, adjusts the padding of this view to leave space for the system windows. Will only take effect if this view is in a non-embedded activity. 
簡單描述: 
這個一個boolean值的內部屬性,讓view可以根據系統窗口(如status bar)來調整自己的佈局,如果值爲true,就會調整view的paingding屬性來給system windows留出空間…. 
實際效果: 
當status bar爲透明或半透明時(4.4以上),系統會設置view的paddingTop值爲一個適合的值(status bar的高度)讓view的內容不被上拉到狀態欄,當在不佔據status bar的情況下(4.4以下)會設置paddingTop值爲0(因爲沒有佔據status bar所以不用留出空間)。

具體適配方案(一邊看代碼一邊解析): 
activity_main.xml:

[html] view plain copy
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     xmlns:tools="http://schemas.android.com/tools"  
  4.     android:layout_width="match_parent"  
  5.     android:layout_height="match_parent"  
  6.     android:orientation="vertical"  
  7.     tools:context=".MainActivity">  
  8.   
  9.     <!--toolbar-->  
  10.     <include  
  11.         layout="@layout/mytoolbar_layout"  
  12.         android:layout_width="match_parent"  
  13.         android:layout_height="wrap_content" />  
  14.     <TextView  
  15.         android:layout_width="match_parent"  
  16.         android:layout_height="match_parent"  
  17.         android:layout_gravity="center"  
  18.         android:gravity="center"  
  19.         android:text="ThinkCool" />  
  20. </LinearLayout>  

這裏我們include了一個mytoolbar_layout的佈局:

mytoolbar_layout.xml:

[html] view plain copy
  1. <android.support.v7.widget.Toolbar xmlns:android="http://schemas.android.com/apk/res/android"  
  2.     xmlns:app="http://schemas.android.com/apk/res-auto"  
  3.     xmlns:tools="http://schemas.android.com/tools"  
  4.     android:id="@+id/my_toolbar"  
  5.     android:layout_width="match_parent"  
  6.     android:layout_height="wrap_content"  
  7.     android:background="@color/colorPrimary"  
  8.     android:fitsSystemWindows="true"  
  9.     android:minHeight="?attr/actionBarSize"  
  10.     android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"  
  11.     app:popupTheme="@style/ThemeOverlay.AppCompat.Light" />  

在mytoolbar_layout.xml裏:佈局一個 android.support.v7.widget.Toolbar(使用支持包裏的toolbar可以兼容低版本android系統),並設置minHeight=”?attr/actionBarSize”和fitSystemWindows爲true。

MainActivity.java:

[java] view plain copy
  1. package com.thinkcool.statusbaradapt;  
  2. import android.os.Bundle;  
  3. import android.support.v7.widget.Toolbar;  
  4.   
  5. public class MainActivity extends BaseActivity {  
  6.     Toolbar toolbar;  
  7.   
  8.     @Override  
  9.     protected void onCreate(Bundle savedInstanceState) {  
  10.         super.onCreate(savedInstanceState);  
  11.         setContentView(R.layout.activity_main);  
  12.         //讓toolbar同actionbar一樣使用,include自定義的topbar時註釋到下面兩句  
  13.         toolbar = (Toolbar) findViewById(R.id.my_toolbar);  
  14.         setSupportActionBar(toolbar);  
  15.     }  
  16. }  

在MainActivity.java裏,繼承BaseAcitivity(後面描述),實例化toolbar並調用setSupportActionBar,之後就可以讓toolbar像action bar一樣使用了。

BaseActivity.java:

[java] view plain copy
  1. package com.thinkcool.statusbaradapt;  
  2.   
  3. import android.os.Build;  
  4. import android.os.Bundle;  
  5. import android.support.v7.app.AppCompatActivity;  
  6. import android.view.Window;  
  7. import android.view.WindowManager;  
  8.   
  9. public class BaseActivity extends AppCompatActivity {  
  10.     @Override  
  11.     protected void onCreate(Bundle savedInstanceState) {  
  12.         super.onCreate(savedInstanceState);  
  13.         if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {  
  14.             Window window = getWindow();  
  15.             // Translucent status bar  
  16.             window.setFlags(  
  17.                     WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS,  
  18.                     WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);  
  19.         }  
  20.     }  
  21. }  

在BaseActivity.java裏:我們通過判斷當前sdk_int大於4.4(kitkat),則通過代碼的形式設置status bar爲透明(這裏其實可以通過values-v19 的sytle.xml裏設置windowTranslucentStatus屬性爲true來進行設置,但是在某些手機會不起效,所以採用代碼的形式進行設置)。還需要注意的是我們這裏的AppCompatAcitivity是android.support.v7.app.AppCompatActivity支持包中的AppCompatAcitivity,也是爲了在低版本的android系統中兼容toolbar。

AndroidManifest.xml中:使用Theme.AppCompat.Light.NoActionBar主題

[html] view plain copy
  1. ....  
  2. <application  
  3.     android:allowBackup="true"  
  4.     android:icon="@mipmap/ic_launcher"  
  5.     android:label="@string/app_name"  
  6.     android:supportsRtl="true"  
  7.     android:theme="Theme.AppCompat.Light.NoActionBar">  
  8. ...  

最後build.gradle中引入v7支持庫(需要注意v7版本得大於21): 
compile ‘com.android.support:appcompat-v7:23.1.1’

看看效果吧(同qq狀態欄效果,依次是:不透明(4.4以下),透明(4.4以上),半透明(5.0以上)): 
Android4.4以下:不佔據status bar 
這裏寫圖片描述

Android4.4以上:全透明(APP 的內容不被上拉到狀態) 
這裏寫圖片描述

Android5.0以上:半透明(APP 的內容不被上拉到狀態) 
這裏寫圖片描述 
這套適配方案的好處: 
1.通過include mytoolbar.xml和mytopbar.xml可以方便的在使用toolbar和使用自定義topbar中進行抉擇。 
2.使用fitSystemWindows屬性讓系統幫我們自動適配不同情況下的status bar,讓我們的view的paddingTop獲取到一個合理的值。(還有其他的方案是通過手動設置paddingTop的值來進行適配的:在values-v19裏設置paddingTop值爲25dp,在values裏設置爲0dp,但是在某些自定義的rom裏status bar的高度是被有修改過的。還有就是通過自定義繼承toolbar,在代碼裏動態獲取status bar的高度並設置paddingTop的值,但這樣又弄得太麻煩了)。

自定義topBar的情況(因爲我們的UI設計師不一定跟得上material design的步伐,而且總是在有着不一樣的設計風格,這個時候自定義topbar就最好了如:qq的topbar就是自定義的):

activity_main.xml

[html] view plain copy
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     xmlns:tools="http://schemas.android.com/tools"  
  4.     android:layout_width="match_parent"  
  5.     android:layout_height="match_parent"  
  6.     android:orientation="vertical"  
  7.     tools:context=".MainActivity">  
  8.   
  9.     <!--toolbar-->  
  10.     <!--<include-->  
  11.         <!--layout="@layout/mytoolbar_layout"-->  
  12.         <!--android:layout_width="match_parent"-->  
  13.         <!--android:layout_height="wrap_content" />-->  
  14.     <!--自定義topbar-->  
  15.     <include  
  16.         layout="@layout/mytopbar_layout"  
  17.         android:layout_width="match_parent"  
  18.         android:layout_height="wrap_content" />  
  19.   
  20.     <TextView  
  21.         android:layout_width="match_parent"  
  22.         android:layout_height="match_parent"  
  23.         android:layout_gravity="center"  
  24.         android:gravity="center"  
  25.         android:text="ThinkCool" />  
  26. </LinearLayout>  

在activity_main.xml裏:include自定義的mytopbar_layout.

mytopbar_layout.xml:

[html] view plain copy
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     android:layout_width="match_parent"  
  4.     android:layout_height="wrap_content"  
  5.     android:background="@color/colorPrimary"  
  6.     android:minHeight="?attr/actionBarSize"  
  7.     android:gravity="center"  
  8.     android:fitsSystemWindows="true"  
  9.     android:orientation="vertical">  
  10.   
  11.     <LinearLayout  
  12.         android:layout_width="match_parent"  
  13.         android:layout_height="wrap_content"  
  14.         android:padding="8dp"  
  15.         android:gravity="center"  
  16.         android:orientation="horizontal">  
  17.         <ImageView  
  18.             android:id="@+id/top_left"  
  19.             android:layout_width="wrap_content"  
  20.             android:layout_height="wrap_content"  
  21.             android:src="@drawable/back" />  
  22.   
  23.         <TextView  
  24.             android:id="@+id/top_center"  
  25.             android:layout_width="wrap_content"  
  26.             android:layout_height="wrap_content"  
  27.             android:layout_gravity="center"  
  28.             android:layout_weight="1"  
  29.             android:gravity="center"  
  30.             android:text="登陸"  
  31.             android:textSize="16sp" />  
  32.   
  33.         <ImageView  
  34.             android:id="@+id/top_right"  
  35.             android:layout_width="wrap_content"  
  36.             android:layout_height="wrap_content"  
  37.             android:src="@drawable/add" />  
  38.     </LinearLayout>  
  39.   
  40.     <View  
  41.         android:layout_width="match_parent"  
  42.         android:layout_height="1px"  
  43.         android:background="@android:color/darker_gray" />  
  44. </LinearLayout>  

修改MainActivity.java:
[java] view plain copy
  1. package com.thinkcool.statusbaradapt;  
  2.   
  3. import android.os.Bundle;  
  4. import android.support.v7.widget.Toolbar;  
  5.   
  6. public class MainActivity extends BaseActivity {  
  7.     Toolbar toolbar;  
  8.   
  9.     @Override  
  10.     protected void onCreate(Bundle savedInstanceState) {  
  11.         super.onCreate(savedInstanceState);  
  12.         setContentView(R.layout.activity_main);  
  13.         //讓toolbar同actionbar一樣使用,include自定義的topbar時註釋到下面兩句  
  14. //        toolbar = (Toolbar) findViewById(R.id.my_toolbar);  
  15. //        setSupportActionBar(toolbar);  
  16.     }  
  17. }  

MainActivity.java裏:我們註釋掉了setSupportActionBar(因爲這是我們自定義的topbar). 
同樣看看實現效果吧: 
Android4.4以下:不佔據status bar 
這裏寫圖片描述

Android4.4以上:全透明(APP 的內容不被上拉到狀態) 
這裏寫圖片描述

Android5.0以上:半透明(APP 的內容不被上拉到狀態) 
這裏寫圖片描述

最後代碼上傳gitHub(歡迎fork,加星): 
https://github.com/CoolThink/StatusBarAdapt.git



syles.xml(定義了顏色屬性)


運行效果圖:

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章