2015-04-01 2 views
0

В моем приложении у меня много чертежей, определенных с помощью xml-файлов. Например, я кнопка определена так:Динамически изменяемые цвета:

button.xml 
<?xml version="1.0" encoding="utf-8"?> 
<layer-list xmlns:android="http://schemas.android.com/apk/res/android"> 
<!-- Bottom 3dp Shadow --> 
<item android:top="3dp"> 
    <shape android:shape="rectangle"> 
      <corners android:radius="3dp" /> 
      <solid android:color="@color/black_30" /> 
    </shape> 
</item> 
<!-- green top color --> 
<item android:top="3dp" android:bottom="3dp" android:id="@+id/background"> 
    <shape android:shape="rectangle"> 
     <corners android:radius="3dp" /> 
     <solid android:color="@color/green1" />   
    </shape> 
</item> 
</layer-list> 

, а затем отобразить кнопку так:

layout.xml 
<Button 
     android:id="@+id/button" 
     android:layout_gravity="center" 
     android:layout_height="60dp" 
     android:layout_width="fill_parent" 
     android:textSize="17sp" 
     android:gravity="center" 
     android:background="@drawable/button" /> 

Когда я провожу в приложении, я хочу, чтобы некоторые виды «тема» (некоторые цвета меняются в зависимости от контекста), и для этого я хотел бы динамически изменять цвет кнопки (green1) во время выполнения.

1) Одним из первых приятных подходов было бы изменить определение цвета в button.xml с помощью ?attr/my_color. И затем определите различные значения цвета, которые мне нужны в файле темы style.xml. Затем во время выполнения я могу переключиться на нужную тему, и это сработает. Полные шаги здесь:

How to reference colour attribute in drawable?

Вопрос заключается в том, что он работает на Android 5, но не на Android 4 (и мне нужно поддерживать эту версию) (мы получаем android.view.InflateException: Binary XML file line #2: Error inflating class <unknown>)

2) Второй подход заключается в загрузке вытяжки в коде, а затем использовать setColor изменить цвет вытяжки: (написано в Xamarin.Android, но я уверен, что вы будете понимать соответствующую версию Java)

LayerDrawable button = (LayerDrawable)Resources.GetDrawable(Resource.Drawable.normal_question_button); 
GradientDrawable background = (GradientDrawable)button.FindDrawableByLayerId(Resource.Id.background); 
background.SetColor(Android.Graphics.Color.Red.ToArgb()); 

Хорошо, что он работает ... но случайно ... Иногда, когда я снова показываю кнопку, это все еще отображается зеленый цвет. Иногда это новый цвет ... И как только у меня есть одно из обоих поведений, один и тот же цвет может оставаться много раз, и вдруг он снова меняется на правильный.

Кто-то может это объяснить? Есть ли кэширование на чертежах, которые могут дать такую ​​проблему?

3) Я думал о третьем решении: динамически изменять цвет, определенный в colors.xml (где green1 определен), но это не представляется возможным

+0

Привет, в моих значках ящика для навигации (с возможностью рисования внутри imageViews), я использую метод setColorFilter. Например, если у меня есть черная иконка 100% непрозрачности, используя этот метод, я могу получить значок с некоторым цветом с непрозрачностью 100%. Объединяя его с setImageAlpha или setAlpha, я могу получить все значки всех цветов во всех непрозрачности. Если это сработает для вас, скажите мне добавить к ответу. – Dahnark

+0

Вы пытались вызвать invalidateSelf() на внешнем LayerDrawable? – pskink

+0

@pskink: я попытался вызвать invalidateSelf() на обоих чертежах, и нет изменений – nicolas

ответ

0

На самом деле для 2) один очень простое решение:

вместо того, чтобы пытаться настроить рисуем исходя из файла XML:

LayerDrawable button = (LayerDrawable)Resources.GetDrawable(Resource.Drawable.normal_question_button); 
GradientDrawable background = (GradientDrawable)button.FindDrawableByLayerId(Resource.Id.background); 
background.SetColor(Android.Graphics.Color.Red.ToArgb()); 

мы можем изменить непосредственно цвет на каждой кнопке, когда мы имеем пример для них:

LayerDrawable buttonDrawable = _button.Background; 
GradientDrawable background = (GradientDrawable)buttonDrawable.FindDrawableByLayerId(Resource.Id.background); 
background.SetColor(Android.Graphics.Color.Red.ToArgb()); 
Смежные вопросы