В моем приложении у меня много чертежей, определенных с помощью 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
определен), но это не представляется возможным
Привет, в моих значках ящика для навигации (с возможностью рисования внутри imageViews), я использую метод setColorFilter. Например, если у меня есть черная иконка 100% непрозрачности, используя этот метод, я могу получить значок с некоторым цветом с непрозрачностью 100%. Объединяя его с setImageAlpha или setAlpha, я могу получить все значки всех цветов во всех непрозрачности. Если это сработает для вас, скажите мне добавить к ответу. – Dahnark
Вы пытались вызвать invalidateSelf() на внешнем LayerDrawable? – pskink
@pskink: я попытался вызвать invalidateSelf() на обоих чертежах, и нет изменений – nicolas