原文地址: Android app的暗黑模式適配實現 - Stars-One的雜貨小窩
很久之前放在草稿箱的一篇簡單筆記,是之前藍奏雲批量下載工具Android版本實現暗黑主題的適配記錄
本文所說的這裏的暗黑主題,應該只支持Android10系統,不過我手頭的Flyme系統(Android9)上測試也有效果,其他低版本則沒有測試(不過之後版本也沒用戶反饋過此問題應該視作都兼容了吧...)
效果的話,沒有搞太複雜,APP的主題會自動隨着系統主題變化(沒搞那種APP內部切換主題)
寫的比較簡陋,各位見笑了 😃
效果
原理說明
Android10開始,支持深色主題,我們想要實現,就是在values
和values-night
下寫2個themes.xml
,裏面使用不同的主題色即可
由於APP開發時間比較久,如果想要適配深色主題,要改的地方可太多了
於是我這裏就是選擇了亮色和暗色都設置一套APP的文本顏色和背景顏色,之後即可對全局APP的文字和組件背景色進行覆蓋,從而一鍵式完成暗黑模式的適配工作
顏色文件:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="colorPrimary">#03A9F4</color>
<color name="colorPrimaryDark">#0288D1</color>
<color name="colorAccent">#40C4FF</color>
<color name="colorGrey">#9e9e9e</color>
<color name="colorBlack">#000000</color>
<color name="colorBackground">#f1f1f1</color>
<color name="color_rose">#dd1c73</color>
</resources>
亮色主題:
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.MaterialComponents.Light.NoActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<!--用作背景色 -->
<item name="colorOnPrimary">@color/white</item>
<!-- 第二背景色,與上面的反過來 -->
<item name="colorOnSecondary">@color/gray_600</item>
<item name="colorAccent">@color/colorAccent</item>
<item name="android:textColor">@color/black</item>
<item name="backgroundColor">@color/colorPrimary</item>
<item name="android:statusBarColor">?attr/colorPrimary</item>
</style>
暗色主題:
<style name="AppTheme" parent="Theme.MaterialComponents.DayNight.NoActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">@color/colorPrimaryDark</item>
<item name="colorPrimaryDark">@color/colorPrimary</item>
<!--用作背景色 -->
<item name="colorOnPrimary">@color/black</item>
<item name="colorOnSecondary">@color/white</item>
<item name="colorAccent">@color/colorAccent</item>
<item name="android:textColor">@color/white20</item>
<item name="backgroundColor">@color/colorPrimaryDark</item>
<item name="android:statusBarColor">?attr/colorPrimary</item>
</style>
上文提到的3個屬性即是覆蓋了系統的文本顏色和背景顏色,因爲APP是沉浸式狀態欄設計,所以我狀態欄的顏色也一起設置了
<item name="android:textColor">@color/white20</item>
<item name="backgroundColor">@color/colorPrimaryDark</item>
<item name="android:statusBarColor">?attr/colorPrimary</item>
PS:上述我設置的暗色主題的字體顏色是有點灰色white20
,各位可以看着調整下
官方的推薦是使用下面4個屬性:
?attr/colorControlNormal
一種通用圖標顏色。該顏色包含一個停用狀態?android:attr/textColorPrimary
: 這是一種通用型文本顏色。它在淺色主題背景下接近於黑色,在深色主題背景下接近於白色。該顏色包含一個停用狀態。?attr/colorSurface
:它代表表面的顏色,通常是應用程序的主要背景色或容器的背景色。在淺色主題中,通常爲白色或淺灰色,在深色主題中,通常爲黑色或深灰色。?attr/colorOnSurface
:屬性用於設置界面元素的前景顏色,如文本、圖標等。它代表了在 colorSurface 背景上顯示的顏色。在淺色主題中,通常爲深色(如黑色)以提供對比度,在深色主題中,通常爲淺色(如白色)。
如果是在剛開始寫一個新的APP,注意使用上述顏色,之後就比較好的可以支持暗黑模式了,如下面代碼
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="開始說明"
android:textColor="?android:attr/textColorPrimary"
android:textSize="18sp"
android:textStyle="bold" />
其他補充
1.Toolbar顏色變黑色
這裏發現設置的Toolbar在暗黑模式下是變爲了黑色,但是我不想要黑色,想要我自己設置的暗一點藍色效果,於是使用了MaterialToolbar
,並對其進行了屬性的設置就可達到需要的效果
<com.google.android.material.appbar.MaterialToolbar
android:id="@+id/toolbar"
app:layout_constraintTop_toTopOf="parent"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/colorPrimary"
app:navigationIconTint="?attr/colorOnPrimary"
app:popupTheme="@style/AppTheme"
app:theme="@style/AppTheme"
app:titleTextColor="?attr/colorOnPrimary"
app:title="@string/app_name"/>
background
背景色navigationIconTint
左側導航圖標(返回箭頭)的圖標顏色titleTextColor
Toolbar的標題顏色
2.獲取顏色代碼方法
想要在代碼裏獲取?android:attr/textColorPrimary
這個顏色,如何獲取?
@ColorInt
fun Context.getColorResCompat(@AttrRes id: Int): Int {
val resolvedAttr = TypedValue()
this.theme.resolveAttribute(id, resolvedAttr, true)
val colorRes = resolvedAttr.run { if (resourceId != 0) resourceId else data }
return ContextCompat.getColor(this, colorRes)
}
使用:
val color = getColorResCompat(android.R.attr.textColorPrimary)
textview.setTextColor(color)