动态改变可绘制的颜色

时间:2015-04-01 14:28:07

标签: java c# android xamarin.android android-drawable

在我的应用程序中,我有很多用xml文件定义的drawable。例如,我有一个定义如下的按钮:

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

当我在应用中导航时,我希望&#34;主题&#34;一些视图(某些颜色正在改变上下文的功能)并且为此我希望能够在运行时动态地改变按钮(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)第二种方法是在代码中加载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());

好处是它的作品......但随机......有时当我再次显示按钮时,它仍然是显示的原始绿色。有时,它是新的颜色......一旦我有这两种行为中的一种,相同的颜色可以保持很多时间,突然它再次变为正确的颜色。

有人可以解释一下吗?是否有一些缓存可以产生这种问题?

3)我正在考虑第三个解决方案:动态更改colors.xml中定义的颜色(其中green1已定义)但它似乎不可能

1 个答案:

答案 0 :(得分:0)

事实上2)一个非常简单的解决方案是:

而不是尝试自定义来自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());

我们可以直接更改每个按钮上的颜色:

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