android 自定義狀態列和導航欄分析與實現

Shawn_Dut發表於2019-02-26

效果

  android 4.4之後,系統是支援自定義狀態列和導航欄的,舉個最典型的例子就是bilibili客戶端了(iOS版本和android版本能用兩套完全不一樣符合各自系統的設計ui,良心啊~),頂部狀態列為粉色,底部導航欄為半透明色:
  

android 自定義狀態列和導航欄分析與實現
這裡寫圖片描述

  接著QQ最新的版本6.2也使用了狀態列透明風格,但是出來的效果在不同版本,不同手機上,顯示的效果真是差異很大(4.3版本是無法使用狀態列透明風格的,只是放出來做個對比):
  更新,QQ的6.2.1版本已經重新換成藍色的bar了。
  

android 自定義狀態列和導航欄分析與實現
這裡寫圖片描述

————————————————————————————————————
  

android 自定義狀態列和導航欄分析與實現
這裡寫圖片描述

————————————————————————————————————
  

android 自定義狀態列和導航欄分析與實現
這裡寫圖片描述

————————————————————————————————————
  

android 自定義狀態列和導航欄分析與實現
這裡寫圖片描述

————————————————————————————————————
  

android 自定義狀態列和導航欄分析與實現
這裡寫圖片描述

  這個我也不知道到底是怎麼適配的,希望有人給解答一下。

實現與分析

API 19~20

  接下來分析一下怎麼自定義狀態列和導航欄,這個在21版本之前和之後可以使用不同的方式來實現,先看看19~20版本的適配,狀態列和導航欄透明:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <style name="Activity_translucent_status_bar" parent="@style/Theme.AppCompat.Light.NoActionBar">
        <item name="android:windowTranslucentStatus">true</item>
    </style>
    <style name="Activity_translucent_navigation_bar" parent="@style/Theme.AppCompat.Light.NoActionBar">
        <item name="android:windowTranslucentStatus">true</item>
        <item name="android:windowTranslucentNavigation">true</item>
    </style>
</resources>複製程式碼

  從程式碼看到,狀態列透明主要是使用android:windowTranslucentStatus屬性,導航欄透明主要是使用android:windowTranslucentNavigation屬性。當這個屬性設定為true之後,系統欄會變成半透明,並且應用的內容區域也會擴充到系統欄中:
  

android 自定義狀態列和導航欄分析與實現
這裡寫圖片描述

這樣目的是達到了,但是效果肯定是不行的,怎麼解決呢?來學習一下bilibili和QQ的佈局就瞭解了:
  

android 自定義狀態列和導航欄分析與實現
bilibili

  

android 自定義狀態列和導航欄分析與實現
QQ
android 自定義狀態列和導航欄分析與實現
QQ

從圖片中可以很清楚的看到bilibili和QQ都是在頂部放置了一個和status bar一樣高度,自定義顏色的view,status bar高度的獲取方式:

int id = getResources().getIdentifier("status_bar_height", "dimen", "android");
int height = getResources().getDimensionPixelOffset(id);複製程式碼

這樣思路就很清楚了,所有的activity繼承自一個基類activity,基類activity的佈局檔案進行類似的處理,最後也是能夠達到和bilibili客戶端一樣的效果(吐槽一下華為p6的狀態列黑色陰影真心難看):
  

android 自定義狀態列和導航欄分析與實現
這裡寫圖片描述

  github上也有相關庫可以實現一樣的效果,但是原理都差不多。

API 21~++

  21版本和21版本之後,系統增加了更多的選項用來提供使用者修改顏色:
  

android 自定義狀態列和導航欄分析與實現
這裡寫圖片描述

所以可以通過android:colorPrimaryDark屬性來使狀態列變成所需的顏色,android:navigationBarColor屬性來改變導航欄所需要的顏色:

<item name="android:colorPrimaryDark">@color/bar_color</item>
<item name="android:navigationBarColor">@color/half_black_transparent</item>複製程式碼

最後效果:

android 自定義狀態列和導航欄分析與實現
這裡寫圖片描述

貌似這個導航欄是無法使用透明顏色的,那麼導航欄透明的方案這麼做是行不通的,只能繼續使用19版本的方案了:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <style name="Activity_translucent_status_bar" parent="@style/Theme.AppCompat.Light.NoActionBar">
        <item name="android:colorPrimaryDark">@color/bar_color</item>
    </style>
    <style name="Activity_translucent_navigation_bar" parent="@style/Theme.AppCompat.Light.NoActionBar">
        <item name="android:windowTranslucentStatus">true</item>
        <item name="android:windowTranslucentNavigation">true</item>
    </style>
</resources>複製程式碼

最後也當然需要在頂部新增一個status bar高度的自定義view了,最後不同版本,不同機型適配效果:

android 自定義狀態列和導航欄分析與實現
這裡寫圖片描述
android 自定義狀態列和導航欄分析與實現
這裡寫圖片描述

android 自定義狀態列和導航欄分析與實現
這裡寫圖片描述
android 自定義狀態列和導航欄分析與實現
這裡寫圖片描述

  適配效果還算可以,如果有其他更好解決方法的,指點一下,謝謝~

原始碼

  github.com/zhaozepeng/…

相關文章