简体   繁体   English

动态更改可绘制的颜色

[英]Dynamically change drawable colors

In my application I have a lot of drawables defined with xml files. 在我的应用程序中,我有很多用xml文件定义的可绘制对象。 For example I have a button defined like that: 例如,我有一个这样定义的按钮:

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>

and then I display a button like that: 然后显示这样的按钮:

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" />

When I navigate in the app, I want to "theme" some views (some colors are changing in function of the context) and to do that I would like to be able to change dynamically the color of the button (green1) at runtime. 当我在应用程序中导航时,我希望“主题”一些视图(某些颜色随上下文的变化而变化),并且为此我希望能够在运行时动态更改按钮(green1)的颜色。

1) One first nice approach would be to change the color definition in button.xml with an ?attr/my_color . 1)第一个不错的方法是使用?attr/my_color更改button.xml的颜色定义。 And then define the different color values I need in the theme file style.xml . 然后在主题文件style.xml定义我需要的不同颜色值。 Then at runtime, I can switch to the desired theme and that will work. 然后在运行时,我可以切换到所需的主题,这样就可以了。 The complete steps are here: 完整的步骤在这里:

How to reference colour attribute in drawable? 如何在drawable中引用颜色属性?

The issue is that it works on Android 5 but not on Android 4 ( and I need to support this version) (we get an android.view.InflateException: Binary XML file line #2: Error inflating class <unknown> ) 问题是,它可以在Android 5上运行,但不能在Android 4上运行(我需要支持该版本)(我们得到了android.view.InflateException: Binary XML file line #2: Error inflating class <unknown>

2) The second approach is to load the drawable in the code and then use setColor to change the color of the drawable: (written in Xamarin.Android but I am sure that you will understand the corresponding Java version) 2)第二种方法是在代码中加载drawable,然后使用setColor更改drawable的颜色:(用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());

The good things is that it's works... but randomly... Sometimes when I am displaying the button again, it's still the original green that is displayed. 好消息是它可以工作……但是随机……有时当我再次显示按钮时,它仍然是原始的绿色。 Sometimes, it's the new color... And once I have one of the both behaviour, the same color can stay many time and suddenly it changes again to the correct one. 有时,这是一种新的颜色...一旦我同时拥有这两种行为,相同的颜色可能会停留很多时间,突然又变成正确的颜色。

Someone could explain this? 有人可以解释吗? Is there some caching on drawables that can gives that kind of issue? 在可绘制对象上有一些缓存可以解决这种问题吗?

3) I was thinking about a third solution: dynamically change the color defined in colors.xml (where green1 is defined) but it doesn't seem possible 3)I在想的第三溶液:动态地改变在定义的颜色colors.xml (其中green1定义),但它似乎并不可能

In fact for 2) one really simple solution is: 实际上对于2)一个非常简单的解决方案是:

instead of trying to customize the drawable coming from the xml file: 而不是尝试自定义来自xml文件的drawable:

 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());

We can change directly the color on each button once we have an instance for them: 一旦有了它们的实例,我们就可以直接更改每个按钮的颜色:

LayerDrawable buttonDrawable = _button.Background;
GradientDrawable background = (GradientDrawable)buttonDrawable.FindDrawableByLayerId(Resource.Id.background);
background.SetColor(Android.Graphics.Color.Red.ToArgb());

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM