Android 樣式系統 | 主題背景屬性

2022-01-04 谷歌開發者

收錄於話題 #Android 開發技術 136個

在 Android 樣式系統系列的前幾篇文章中,我們介紹了主題背景與樣式的區別,以及為什麼說通過主題背景和公共主題背景屬性來分解您要實現的內容是一個不錯的主意,請點擊連結回顧:

這會讓我們通過創建更少的布局或樣式,以隔離主題背景中的修改。在實際開發中,您通常希望根據主題背景改變顏色,因此您應該始終通過主題背景屬性來引用顏色。這意味著您可以將如下代碼視為有代碼異味 (Code smell):
<View …  android:background="@color/white"/>

相反,您應該使用主題背景屬性,它允許您按主題更改顏色,例如,在深色主題中提供一個不同的值:
<View …  android:background="?attr/colorSurface"/>

https://developer.android.google.cn/guide/topics/ui/look-and-feel/darktheme

即使您當前不支持其他主題 (什麼,您的應用還沒有支持深色主題?),我們依然建議您採用這種方法,因為這樣會讓新主題的採用變得更加簡單。

您可以通過在不同的配置中添加不同的值來改變顏色 (例如,在 res/values/colors.xml 中和在 res/values-night/colors.xml 中的備選值裡均定義 @color/foo),但我們依然建議您使用主題背景屬性來替代它們。對顏色層級的區分,會迫使您給顏色賦予語義化名稱,換句話說,您應該不會在給顏色命名為 @color/white 的同時,又為深色模式提供一個深色變體,這會讓人感到非常困惑。所以,您可能會想要使用一個語義化名稱,例如 @color/background。這種方法帶來的問題是它合併了顏色聲明和具體的值,因此,它並沒有指出顏色是可以或者能夠隨主題背景而變化的。@colors 的變化也會鼓勵您創造更多顏色。如果在不同的情境下要使用具有相同值的、新的語義化命名的顏色 (即,不是背景色但應該使用相同顏色),這時候您仍需要在 colors 文件中創建新的條目。通過使用主題背景屬性,我們可以將語義顏色的聲明從提供它們的值中區分開來,而且讓使用方更清楚地了解到顏色會隨主題背景而變化 (因為它們使用 ?attr/ 語法)。將顏色聲明保持為字面值,您就可以自定義應用使用的顏色調色板,並在主題背景級別修改它們,這會讓 color.xml 較小且易維護。這種方法的額外好處是,布局/樣式引用這些顏色時復用性變得更高。由於主題背景可以被覆蓋或者改變,因此這間接表示: 您不需要創建其他布局或樣式就可以更改某些顏色——您可以在相同的布局中使用不同的主題背景。在某些情況下,您或許不想按照主題背景更改顏色。例如,在 Material Design 規範文檔中提到,您可能希望在淺色和深色主題中均使用同一類型的顏色。
https://material.io/design/color/dark-theme.html#ui-application在這種特殊情況下,直接引用顏色資源是再合適不過的:
<FloatingActionButton …  app:backgroundTint="@color/owl_pink_500"/>

當使用 ColorStateLists 時,您可能也不會在您的布局/樣式中直接引用主題背景屬性。
<View …  android:background="@color/primary_20"/>

https://developer.android.google.cn/reference/android/content/res/ColorStateList如果 primary_20 是一個 ColorStateList,它本身引用主題背景屬性來獲取色值也可能是合理的 (請參見下文)。ColorStateLists 通常為不同的狀態 (按下,禁用等) 提供不同的顏色,但它還有另外一種可用於主題化功能您可在選取的顏色上指定透明度值:
<!-- Copyright 2019 Google LLC.     SPDX-License-Identifier: Apache-2.0 --><selector …  <item android:alpha="0.20" android:color="?attr/colorPrimary" /></selector>

這種單項 ColorStateList (即只提供單個默認顏色,而非每種狀態的不同顏色) 有助於減少您需要維護的顏色資源數量。它並沒有定義一個新的顏色資源的方式來手動為您 (每一個配置文件) 的 primary 顏色設置 alpha 值,而是通過改變當前主題背景中的 colorPrimary 的方式。如果您的原始顏色發生了變化,則只需要在一個地方進行更新,無需調整所有已更新的地方。

 

1. 如果指定的顏色也具有 alpha 值,則 alpha 會被合併。例如,將 50% 的 alpha 應用於 50% 的不透明白色中,將產生 25% 的白色:

<!-- Copyright 2019 Google LLC.     SPDX-License-Identifier: Apache-2.0 --><selector …  <item android:alpha="0.50" android:color="#80ffffff" /></selector>

因此,最好將主題背景顏色指定為完全不透明,然後使用 ColorStateLists 修改它們的 alpha。2. 僅在 API 23 中添加了 alpha 組件,因此,如果您的最小 sdk 低於這個版本,請確保使用支持此行為的 AppCompatResources.getColorStateList (並始終使用 android:alpha 命名空間,而絕不使用 app:alpha 命名空間)。AppCompatResources.getColorStateListhttps://developer.android.google.cn/reference/androidx/appcompat/content/res/AppCompatResources.html#getColorStateList(android.content.Context,%20int)3. 通常,我們使用簡寫法,將顏色設置為 Drawable,例如:
<View …  android:background="@color/foo"/>

View 的背景是一個 Drawable,此簡寫把給定的顏色強轉成了一個 ColorDrawable。但是沒有辦法把 ColorStateList 轉換成 Drawable (API 29 之前使用 ColorStateListDrawable 解決這個問題)。https://developer.android.google.cn/reference/android/graphics/drawable/ColorDrawablehttps://developer.android.google.cn/reference/android/graphics/drawable/ColorStateListDrawable

 

<View …  android:background="@drawable/a_solid_white_rectangle_shape_drawable"  app:backgroundTint="@color/some_color_state_list"/>

請確保您的 backgroundTint 支持您的 View 所需的狀態,例如,如果被禁用時需要更改。即使您已經說服自己使用主題背景屬性和 ColorStateList,但如何在代碼庫或者團隊中使用呢?您可以在 Code review 期間嘗試保持警惕,但它的擴展性不是很好。更好的方法是依靠工具來解決此問題。
《Making Android Lint Theme Aware》這篇文章簡述了如何通過添加 Lint 檢查來尋找直接引用顏色的用法,並涵蓋了文中提及到的所有建議。使用主題背景屬性和 ColorStateList 將顏色分解為主題背景的方法,可使您的布局和樣式更加靈活,提高代碼復用性並保持代碼庫的精簡和易維護性。我們將在後續文章中介紹更多主題背景的用法以及它們之間的相互影響,感興趣的讀者請繼續關注。 點擊屏末  | 了解更多與 Android 界面相關的內容和教程

相關焦點

  • Android 屬性動畫詳解,屬性動畫基本用法
    因為這個View實際還在原來的位置,只不過補間動畫將這個View繪製的地方向右移動了20px,而這個View真正的屬性並沒有改變。通過上面的介紹,相信大家已經明白了屬性動畫產生的原因,了解了它產生的背景之後,接下來的一步就是要學習它的用法了。
  • Android屬性動畫:這是一份全面 & 詳細的核心使用類ObjectAnimator學習攻略
    ="http://schemas.android.com/apk/res/android" android:valueFrom="1" // 初始值 android:valueTo="0" // 結束值 android:valueType="floatType" // 變化值類型 :floatType & intType
  • Android 轉場動畫
    Android L 是Google於2014年升級的系統版本號, 在2015年國內廠商新機就開始推送Android L, 現在是2017年我覺得此時不用更待何時.在android.transition包下提供關於transitionAnimation的過渡框架, Transiton框架是在api19引入, 但是轉場動畫卻是在api21引入.
  • android app殺死啟動專題及常見問題 - CSDN
    應用的啟動過程冷啟動啟動流程——當點擊app的啟動圖標時,安卓系統會從Zygote進程中fork創建出一個新的進程分配給該應用,之後會依次創建和初始化Application類(attachBaseContext()–>OnCreate())、創建MainActivity類、加載主題樣式Theme中的 windowBackground等屬性設置給MainActivity以及配置Activity
  • 對於Android Button,你可能並不了解
    屬性描述android:button設置一張圖片來作為顯示android:buttonTint渲染顏色android:buttonTintMode渲染模式android:checked設置為選中狀態用來重寫進行自定義控制項的方法我不夠熟悉我就不講了.設置選擇狀態可以通過設置參數在選中和未選中的狀態之間切換.
  • 開發你的第一個 Android 應用
    作為根元素,LinearLayout部件必須指定Android XML資源文件的命名空間屬性。LinearLayout部件繼承自ViewGroup部件(也是一個View子類)。ViewGroup部件是包含並布置其他視圖的特殊視圖。想要以一列或一排的樣式布置部件,就可以使用LinearLayout部件。
  • Android 中的轉場動畫及兼容處理
    湫水的博客地址:http://blog.csdn.net/wl9739Android 中的動畫有很多,除了在一個界面上使用幀動畫、屬性動畫將一個或多個 View 進行動畫處理以外,還可以用於兩個界面之間過渡、跳轉。在 Android 5.0 之前,我們已經有了 overridePendingTransition() 方法來實現一些轉場效果。
  • Android TV開發簡介
    下面的例子展示了一個基本的AndroidMainifest:<application  android:banner="@drawable/banner" >  ...  <activity    android:name="com.example.android.MainActivity"    android:label="@string/app_name" >    <intent-filter>      <action android:name="android.intent.action.MAIN" />      <
  • 使用Android Studio編寫系統APP
    當我們需要寫一些系統內置的APP時,比如Launcher, Setting之類的,它們經常會使用到一些隱藏的API,而這些API在SDK裡是找不到的,或者使用一些我們自己ROM裡編寫的接口,這時候我們就需要引用我們自己的framework.jar, 否則Android Studio裡是編譯不過的。
  • 這15個Android開源庫,只有經常逛Github的才知道!
    使用非常簡單,並且可以自定義,你可以在在styles.xml下添加自定義樣式。<item name="android:textColor">#000</item></style>然後,您應該將樣式設置為MultiSearchView下的app:searchTextStyle。
  • Android性能優化-過渡繪製解決方案
    但是Android系統在繪製時會將下層的卡片進行繪製,接著再將上層的卡片進行繪製。但其實,下層卡片不可見的部分是不需要進行繪製的,只有可見部分才需要進行繪製。 去除Activity自帶的默認背景顏色: 查看Android源碼裡的Theme主題,如下:
  • Android Studio啟用新代號!新版本Artic Fox重點新特性一覽!
    如果沿用以前的編號系統,則此版本將為 Android Studio 4.3。現在,新版編號系統將其命名為 Android Studio Arctic Fox (2020.3.1) Canary 1,或簡稱為 Arctic Fox。為什麼要更改命名方案呢?
  • Android幀動畫和補間動畫看這篇足夠了
    幀動畫依然在這個複雜而有機的 Android 系統中佔有一席之地。先來告訴大家幀動畫的使用場景吧。設備的開機動畫及其「複雜」的效果,看似不可能完成的動畫設備的開機動畫界面這個沒什麼好解釋的,據我所知市面上99%的機器都是這麼做的,因為這個時候系統或資源還沒準備完全,所以就肯定會選擇幀動畫。
  • DevFest·北京 - Android 主題內容介紹
    主題:把玩 Android 多進程從實踐的角度來介紹下android中的多進程概念,講解一些大家容易誤解的進程間通信細節。本主題比較系統地討論在處理「異步任務」過程中的編程模式,主要內容包括:1. 異步任務舉例和線程模型。2. 執行多個異步任務的三種協作模式。3. 任務隊列中的異步處理。4. 異步任務取消和暫停的正確方式。5. 異步處理和響應式編程。
  • GitHub Top 100的Android開源庫
    MPAndroidChartMPAndroidChart 是一款強大的 Android 圖表庫, 支持各種各樣圖表顯示, 能想到的圖表樣式這裡幾乎都有, 圖表還支持選擇, 拖放和縮放動畫效果16.ShowcaseViewShowcaseView 是一個非常適合用於對用戶進行第一次使用進行指導的庫,使用起來非常簡單還可以自定義樣式54.
  • Android Studio啟用新代號,新版本Arctic Fox(白狐)重點新特性一覽!
    如果沿用以前的編號系統,則此版本將為 Android Studio 4.3。現在,新版編號系統將其命名為 Android Studio Arctic Fox (2020.3.1) Canary 1,或簡稱為 Arctic Fox。為什麼要更改命名方案呢?
  • Android | 爆肝兩天!我寫了一個支持圓角、描邊的UI庫
    寫 xml 文件,設置圓角背景在 drawable 文件夾下,新建 xml 文件,通過 shape 標籤來設置圓角半徑,描邊寬度和顏色。然後將它設置為某個具體 View 的背景即可。><shape xmlns:android="http://schemas.android.com/apk/res/android"    android:shape="rectangle">    <corners android:radius="10dp" />    <solid android:color="@color/colorAccent
  • Android之屬性動畫Animator
    於是3.0之後,Google提出了屬性動畫。><objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"android:duration="2000"android:propertyName="alpha"android:valueFrom="0.1"android:valueTo="1.0"android