欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

分析Android多主題顏色的相關(guān)問題

 更新時(shí)間:2016年08月16日 10:06:56   投稿:daisy  
這篇文章總結(jié)了在Android開發(fā)多主題顏色的時(shí)候會遇到的一些問題,然后給出解決方案,讓大家可以解決問題,有需要的下面一起來看看吧。

如果您通過以下的代碼來獲取定義的顏色值

context.getResources().getColor(R.color.some_color_resource_id);

在 Android Studio 中會有一個(gè) lint 警告,提示您 Resources#getColor(int)Marshmallow 中被廢棄了,建議使用主題可知的 Resources#getColor(int, Theme) 函數(shù)。 為了避免該警告,則可以使用 ContextCompat

ContextCompat.getColor(context, R.color.some_color_resource_id);

該函數(shù)的實(shí)現(xiàn)是這樣的:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
 return context.getResources().getColor(id, context.getTheme());
} else {
 return context.getResources().getColor(id);
}

看起來很簡單。但是為什么會這樣呢? 為什么會開始使用帶主題的函數(shù)而廢棄之前的函數(shù)呢?

Resources#getColor(int) & Resources#getColorStateList(int) 的問題

首先來看看這兩個(gè)被廢棄的函數(shù)是干啥的:
      – Resources#getColor(int) 返回一個(gè)資源 id 對應(yīng)的顏色值,如果該資源為 ColorStateList 則返回 ColorStateList 的默認(rèn)顏色值

      – Resources#getColorStateList(int) 返回對應(yīng)的 ColorStateList

上面的代碼在什么情況下會破壞我的代碼呢?

要理解為何廢棄這兩個(gè)函數(shù),來看個(gè) ColorStateList 的例子。 當(dāng)在 TextView 中使用自定義的 ColorStateList 的時(shí)候, TextView 不可用狀態(tài)和可用狀態(tài)的文字顏色分別使用 R.attr.colorAccentR.attr.colorPrimary 表示。

XHTML

<selector xmlns:android="http://schemas.android.com/apk/res/android">
  <item android:color="?attr/colorAccent" android:state_enabled="false"/>
  <item android:color="?attr/colorPrimary"/>
</selector>

現(xiàn)在如果您通過如下的代碼來獲取這個(gè)ColorStateList

ColorStateList csl = context.getResources().getColorStateList(R.color.button_text_csl);

上面的代碼會拋出一個(gè)異常(查看logcat 可以看到如下的信息)

W/Resources: ColorStateList color/button_text_csl has unresolved theme attributes!
       Consider using Resources.getColorStateList(int, Theme)
       or Context.getColorStateList(int)
    at android.content.res.Resources.getColorStateList(Resources.java:1011)
    ...

哪里出錯(cuò)了呢?

問題的根源在于 Resources 對象并沒有和一個(gè) Theme 對象關(guān)聯(lián),當(dāng)使用 R.attr.colorAccent R.attr.colorPrimary 指代顏色的時(shí)候,在代碼中通過上面的函數(shù)解析的時(shí)候沒有指定對應(yīng)的 Theme導(dǎo)致無法解析出結(jié)果。 所以在 Marshmallow 中添加了 ColorStateList 對 Theme 的支持并且添加了這兩個(gè)新的函數(shù):Resources#getColor(int, Theme) Resources#getColorStateList(int, Theme),并使用 Theme 參數(shù)來解析里面的 attributes 屬性。

在新版本的 Support 庫中也有對應(yīng)的實(shí)現(xiàn),分別位于 ResourcesCompat ContextCompat 類中。

如何解決該問題呢?

使用 AppCompat v24+ 版本可以很容易的解決該問題。

ColorStateList csl = AppCompatResources.getColorStateList(context, R.color.button_text_csl);

在 23+ 版本上直接使用系統(tǒng)的函數(shù),在之前的版本上 AppCompat 自己解析這些 xml 文件從里面提取 attr 屬性指代的數(shù)值。 AppCompat 同時(shí)還支持 ColorStateList 新的 android:alpha 屬性。

Resources#getDrawable(int) 的問題

Resources#getDrawable(int) 和前面的兩個(gè)函數(shù)的問題是類似的。 在 Lollipop 之前的版本中無法支持 Theme attr 。

為啥我這樣用也沒有出現(xiàn)異常呢?

異常并不總是會出現(xiàn)。

VectorDrawableCompatAnimatedVectorDrawableCompat 類中添加了和 AppCompatResources 類類似的功能。比如在 矢量圖中你可以使用 ?attr/colorControlNormal 來設(shè)置矢量圖的顏色,VectorDrawableCompat 會自動完成解析該 屬性的工作:

XHTML

<vector 
  xmlns:android="http://schemas.android.com/apk/res/android"
  android:width="24dp"
  android:height="24dp"
  android:viewportWidth="24.0"
  android:viewportHeight="24.0"
  android:tint="?attr/colorControlNormal">
 
  <path
    android:pathData="..."
    android:fillColor="@android:color/white"/>
</vector>

小測試

下面使用一個(gè)小測試來回顧一下前面介紹的內(nèi)容。 假設(shè)有下面一個(gè) ColorStateList:

XHTML

<!-- res/colors/button_text_csl.xml -->
<selector xmlns:android="http://schemas.android.com/apk/res/android">
  <item android:color="?attr/colorAccent" android:state_enabled="false"/>
  <item android:color="?attr/colorPrimary"/>
</selector>

在應(yīng)用中定義了如下的 Theme:

XHTML

<!-- res/values/themes.xml -->
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
  <item name="colorPrimary">@color/vanillared500</item>
  <item name="colorPrimaryDark">@color/vanillared700</item>
  <item name="colorAccent">@color/googgreen500</item>
</style>
 
<style name="CustomButtonTheme" parent="ThemeOverlay.AppCompat.Light">
  <item name="colorPrimary">@color/brown500</item>
  <item name="colorAccent">@color/yellow900</item>
</style>

在代碼中有如下的函數(shù)用來解析顏色值并在代碼中創(chuàng)建 ColorStateList:

@ColorInt
private static int getThemeAttrColor(Context context, @AttrRes int colorAttr) {
 TypedArray array = context.obtainStyledAttributes(null, new int[]{colorAttr});
 try {
  return array.getColor(0, 0);
 } finally {
  array.recycle();
 }
}
 
private static ColorStateList createColorStateList(Context context) {
 return new ColorStateList(
   new int[][]{
     new int[]{-android.R.attr.state_enabled}, // Disabled state.
     StateSet.WILD_CARD,            // Enabled state.
   },
   new int[]{
     getThemeAttrColor(context, R.attr.colorAccent), // Disabled state.
     getThemeAttrColor(context, R.attr.colorPrimary), // Enabled state.
   });
}

 看看是否能猜出在 API 19 和 API 23 版本上文字禁用狀態(tài)和正常狀態(tài)的顏色,實(shí)現(xiàn)代碼如下(5和8的情況,在TextView xml 中指定了 android:theme=”@style/CustomButtonTheme” ):

Resources res = ctx.getResources();
 
// (1)
int deprecatedTextColor = res.getColor(R.color.button_text_csl);
button1.setTextColor(deprecatedTextColor);
 
// (2)
ColorStateList deprecatedTextCsl = res.getColorStateList(R.color.button_text_csl);
button2.setTextColor(deprecatedTextCsl);
 
// (3)
int textColorXml = 
  AppCompatResources.getColorStateList(ctx, R.color.button_text_csl).getDefaultColor();
button3.setTextColor(textColorXml);
 
// (4)
ColorStateList textCslXml = AppCompatResources.getColorStateList(ctx, R.color.button_text_csl);
button4.setTextColor(textCslXml);
 
// (5)
Context themedCtx = button5.getContext();
ColorStateList textCslXmlWithCustomTheme =
  AppCompatResources.getColorStateList(themedCtx, R.color.button_text_csl);
button5.setTextColor(textCslXmlWithCustomTheme);
 
// (6)
int textColorJava = getThemeAttrColor(ctx, R.attr.colorPrimary);
button6.setTextColor(textColorJava);
 
// (7)
ColorStateList textCslJava = createColorStateList(ctx);
button7.setTextColor(textCslJava);
 
// (8)
Context themedCtx = button8.getContext();
ColorStateList textCslJavaWithCustomTheme = createColorStateList(themedCtx);
button8.setTextColor(textCslJavaWithCustomTheme);

下面是對應(yīng)的實(shí)現(xiàn)截圖:

 

總結(jié) 

以上就是關(guān)于分析Android多主題顏色的相關(guān)問題的全部內(nèi)容,希望本文的內(nèi)容對大家開發(fā)Android能有所幫助。

相關(guān)文章

最新評論