Android:在运行时改变形状颜色

时间:2022-11-21 14:45:58

I have a drawable that i use as a Background for a LinearLayout. I would like to change the color of this Shape in runtime. I have tried using several methods.. but none work.

我有一个drawable,用来作为线性布局的背景。我想在运行时改变这个形状的颜色。我已经试过几种方法了。但没有工作。

I've followed the approach described here: http://www.anddev.org/android-2d-3d-graphics-opengl-problems-f55/change-shape-drawable-solid-color-t16798.html

我遵循了这里描述的方法:http://www.anddev.org/android-2d-3d-graphics-opengl-problems-f55/change- shapedrawable -solid-color-t16798.html

But have the same problem... it doesnt crashes.. but the color doesnt change!

但也有同样的问题……它不崩溃. .但是颜色没有变化!

<?xml version="1.0" encoding="UTF-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
    <solid android:color="#00A6C1" />
    <corners android:radius="@dimen/square_corners" />
</shape>

Snippet of code:

的代码片段:

GradientDrawable drawable = (GradientDrawable) activity.getResources().getDrawable(R.drawable.blue_square_shape);


int color = ((Application) getApplication()).getColor();
drawable.setColor(color);

block.findViewById(R.id.blockSquare).setBackgroundDrawable(drawable);

findViewById(R.id.blockSquare).postInvalidate();

Any clue? I've passed the whole day googling... and it's getting pretty annoying...

有线索吗?我用谷歌搜索了一整天……这很烦人……

UPDATE:

更新:

When i try to do the same to this Shape:

当我尝试对这个形状做同样的事情:

<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/shape" android:shape="rectangle">
    <gradient android:startColor="#1FBCCF" android:endColor="#06A4C1"
        android:angle="270" />
    <corners android:topLeftRadius="@dimen/footer_corners"
        android:topRightRadius="@dimen/footer_corners" />
</shape>

The color turns to black... what i guess tells it can be changed...

颜色变成了黑色……我猜这说明它是可以改变的……

8 个解决方案

#1


40  

I'm now creating a Drawable like the one pre-compiler.. as i couldn't change the color to anything but black, even after trying the hex OR described below.

我现在正在创建一个可绘制的,就像一个预编译器。因为我无法改变颜色,除了黑色,即使尝试了十六进制或描述如下。

The new code:

新代码:

ShapeDrawable footerBackground = new ShapeDrawable();

// The corners are ordered top-left, top-right, bottom-right,
// bottom-left. For each corner, the array contains 2 values, [X_radius,
// Y_radius]
float[] radii = new float[8];
radii[0] = activity.getResources().getDimension(R.dimen.footer_corners);
radii[1] = activity.getResources().getDimension(R.dimen.footer_corners);

radii[2] = activity.getResources().getDimension(R.dimen.footer_corners);
radii[3] = activity.getResources().getDimension(R.dimen.footer_corners);

footerBackground.setShape(new RoundRectShape(radii, null, null));

int color = ((Application) activity.getApplication()).getColor();

footerBackground.getPaint().setColor(color);

views.setBackgroundDrawable(footerBackground);

Anyway this is a fix.. a solution for the first question is what i'm really looking for! I'll appreciate any help of course!

无论如何,这是一个修复。第一个问题的答案就是我真正想要的!我当然感谢任何帮助!

#2


33  

See if something similar to this works for you:

看看类似的东西是否适合你:

TextView tv2 = (TextView) rl.findViewById(R.id.toggle_indicator);
/* Refer to http://developer.android.com/reference/android/graphics/drawable/GradientDrawable.html#mutate()
to understand why we need to mutate the GradientDrawable*/
GradientDrawable sd = (GradientDrawable) tv2.getBackground().mutate();
sd.setColor(0xff999999);
sd.invalidateSelf();

In my case I have a TextView which has a ShapeDrawable as a background. I wanted to change its color and managed to make this work. Inexplicably, tv2.getBackground() returns a GradientDrawable instead of a ShapeDrawable -- this has been reported elsewhere as well.

在我的例子中,我有一个TextView它有一个可图形绘制的背景。我想改变它的颜色,并设法使它工作。令人费解的是,tv2.getBackground()返回了一个渐变,而不是一个ShapeDrawable—这在其他地方也有报道。

Edit: About the color, try setting an alpha value of 0xff. If you notice, even in my code above the setColor() function takes an extra hex value apart from the regular RGB hex value. This is for Alpha/Opacity. If this is set to 0x00 the Drawable will have a black color, irrespective of the RGB (assuming that your background color is black). 0x00 is a completely transparent object & 0xff is a completely opaque object.

编辑:关于颜色,尝试设置0xff的alpha值。如果您注意到,即使在我上面的代码中,setColor()函数除了常规的RGB十六进制值外,还需要额外的十六进制值。这是α/不透明。如果将其设置为0x00,那么可绘制文件将具有黑色,与RGB无关(假设您的背景颜色是黑色)。0x00是一个完全透明的对象,0xff是一个完全不透明的对象。

#3


27  

GradientDrawable background = (GradientDrawable) titleTextView.getBackground();
background.setColor(getResources().getColor(R.color.some_color));

The setColor method correctly requests a redraw on the element (If in xml you used the <shape> element it will always become a GradientDrawable)

setColor方法正确地请求对元素重新绘制(如果在xml中使用 元素,它将始终成为一个可渐变绘制的元素)

#4


4  

There is an easier way:

有一个更简单的方法:

ShapeDrawable drawable = new ShapeDrawable();
drawable.getPaint().setColor(getResources().getColor(R.color.blue));
getActionBar().setBackgroundDrawable(drawable);

#5


3  

R.drawable.library_cirecle

R.drawable.library_cirecle

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:id="@+id/outerRectangle">
    <shape android:shape="oval" >
        <solid android:color="#FCD366" />

        <stroke
            android:width="1dp"
            android:color="@android:color/darker_gray" />
    </shape>
</item>

Change color in code

改变颜色的代码

Drawable tempDrawable = getResources().getDrawable(R.drawable.library_cirecle);
LayerDrawable bubble = (LayerDrawable) tempDrawable; (cast to root element in xml)
GradientDrawable solidColor = (GradientDrawable) bubble.findDrawableByLayerId(R.id.outerRectangle);
solidColor.setColor(colorToPaint);
imageView.setImageDrawable(tempDrawable);

#6


1  

This is what I'm doing in a live wallpaper where I modify a Drawable at runtime:

这就是我在实时壁纸中所做的,我在运行时修改一个可绘制的:

this.original = DrawableFactory.getDrawable(getContext().getResources(), objectName)[0];
originalBitmap = original.getBitmap();
copy = new BitmapDrawable(getContext().getResources(), original.getBitmap().copy(Bitmap.Config.ARGB_8888, true));
copyCanvas = new Canvas(copy.getBitmap());

Edit: Type declarations:

编辑:类型声明:

public Bitmap originalBitmap;
public BitmapDrawable original;
public BitmapDrawable copy;
public Canvas copyCanvas;

Edit 2:

编辑2:

Try this in that case:

在这种情况下试试这个:

int color = (0xFF000000 | yourParsedColor)

Then set that color.

然后设置颜色。

#7


-1  

My current fix involves having a drawable without the color option. I put it inside a frame layout, and then set the background color of the frame layout object dynamically. It's still technically a 'fix,' but it's the most simple option in my opinion.

我目前的解决方案是在没有颜色选项的情况下进行绘制。我把它放在一个框架布局中,然后动态设置框架布局对象的背景颜色。从技术上来说,这仍是一种“修复”,但在我看来,这是最简单的选择。

Layout File:

布局文件:

<FrameLayout
    android:id="@+id/dateLayout"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:background="@color/SecondaryGreen">

    <ImageView
        android:id="@+id/dateBox"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@drawable/date_rectangle" />

</FrameLayout>

Date Rectangle Drawable File:

日期矩形可拉的文件:

<shape xmlns:android="http://schemas.android.com/apk/res/android" ><size android:width="50dp" android:height="50dp"/><corners android:radius="5dp"/></shape>

Dynamic Rendering:

动态呈现:

mHolder.dateLayout.setBackgroundColor(getResources().getColor(R.color.SecondaryGreen));

#8


-1  

Set GradientDrawable Shape color using hex code/value
Simply prefix 0x to hexadecimal color value.

使用十六进制代码/值简单地将前缀0x设置为十六进制颜色值。

    GradientDrawable shape =  new GradientDrawable();
    shape.setCornerRadius( 16 );
    shape.setColor(0xff33b5e5);
    ButtonStartSurvey.setBackground(shape);

#1


40  

I'm now creating a Drawable like the one pre-compiler.. as i couldn't change the color to anything but black, even after trying the hex OR described below.

我现在正在创建一个可绘制的,就像一个预编译器。因为我无法改变颜色,除了黑色,即使尝试了十六进制或描述如下。

The new code:

新代码:

ShapeDrawable footerBackground = new ShapeDrawable();

// The corners are ordered top-left, top-right, bottom-right,
// bottom-left. For each corner, the array contains 2 values, [X_radius,
// Y_radius]
float[] radii = new float[8];
radii[0] = activity.getResources().getDimension(R.dimen.footer_corners);
radii[1] = activity.getResources().getDimension(R.dimen.footer_corners);

radii[2] = activity.getResources().getDimension(R.dimen.footer_corners);
radii[3] = activity.getResources().getDimension(R.dimen.footer_corners);

footerBackground.setShape(new RoundRectShape(radii, null, null));

int color = ((Application) activity.getApplication()).getColor();

footerBackground.getPaint().setColor(color);

views.setBackgroundDrawable(footerBackground);

Anyway this is a fix.. a solution for the first question is what i'm really looking for! I'll appreciate any help of course!

无论如何,这是一个修复。第一个问题的答案就是我真正想要的!我当然感谢任何帮助!

#2


33  

See if something similar to this works for you:

看看类似的东西是否适合你:

TextView tv2 = (TextView) rl.findViewById(R.id.toggle_indicator);
/* Refer to http://developer.android.com/reference/android/graphics/drawable/GradientDrawable.html#mutate()
to understand why we need to mutate the GradientDrawable*/
GradientDrawable sd = (GradientDrawable) tv2.getBackground().mutate();
sd.setColor(0xff999999);
sd.invalidateSelf();

In my case I have a TextView which has a ShapeDrawable as a background. I wanted to change its color and managed to make this work. Inexplicably, tv2.getBackground() returns a GradientDrawable instead of a ShapeDrawable -- this has been reported elsewhere as well.

在我的例子中,我有一个TextView它有一个可图形绘制的背景。我想改变它的颜色,并设法使它工作。令人费解的是,tv2.getBackground()返回了一个渐变,而不是一个ShapeDrawable—这在其他地方也有报道。

Edit: About the color, try setting an alpha value of 0xff. If you notice, even in my code above the setColor() function takes an extra hex value apart from the regular RGB hex value. This is for Alpha/Opacity. If this is set to 0x00 the Drawable will have a black color, irrespective of the RGB (assuming that your background color is black). 0x00 is a completely transparent object & 0xff is a completely opaque object.

编辑:关于颜色,尝试设置0xff的alpha值。如果您注意到,即使在我上面的代码中,setColor()函数除了常规的RGB十六进制值外,还需要额外的十六进制值。这是α/不透明。如果将其设置为0x00,那么可绘制文件将具有黑色,与RGB无关(假设您的背景颜色是黑色)。0x00是一个完全透明的对象,0xff是一个完全不透明的对象。

#3


27  

GradientDrawable background = (GradientDrawable) titleTextView.getBackground();
background.setColor(getResources().getColor(R.color.some_color));

The setColor method correctly requests a redraw on the element (If in xml you used the <shape> element it will always become a GradientDrawable)

setColor方法正确地请求对元素重新绘制(如果在xml中使用 元素,它将始终成为一个可渐变绘制的元素)

#4


4  

There is an easier way:

有一个更简单的方法:

ShapeDrawable drawable = new ShapeDrawable();
drawable.getPaint().setColor(getResources().getColor(R.color.blue));
getActionBar().setBackgroundDrawable(drawable);

#5


3  

R.drawable.library_cirecle

R.drawable.library_cirecle

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:id="@+id/outerRectangle">
    <shape android:shape="oval" >
        <solid android:color="#FCD366" />

        <stroke
            android:width="1dp"
            android:color="@android:color/darker_gray" />
    </shape>
</item>

Change color in code

改变颜色的代码

Drawable tempDrawable = getResources().getDrawable(R.drawable.library_cirecle);
LayerDrawable bubble = (LayerDrawable) tempDrawable; (cast to root element in xml)
GradientDrawable solidColor = (GradientDrawable) bubble.findDrawableByLayerId(R.id.outerRectangle);
solidColor.setColor(colorToPaint);
imageView.setImageDrawable(tempDrawable);

#6


1  

This is what I'm doing in a live wallpaper where I modify a Drawable at runtime:

这就是我在实时壁纸中所做的,我在运行时修改一个可绘制的:

this.original = DrawableFactory.getDrawable(getContext().getResources(), objectName)[0];
originalBitmap = original.getBitmap();
copy = new BitmapDrawable(getContext().getResources(), original.getBitmap().copy(Bitmap.Config.ARGB_8888, true));
copyCanvas = new Canvas(copy.getBitmap());

Edit: Type declarations:

编辑:类型声明:

public Bitmap originalBitmap;
public BitmapDrawable original;
public BitmapDrawable copy;
public Canvas copyCanvas;

Edit 2:

编辑2:

Try this in that case:

在这种情况下试试这个:

int color = (0xFF000000 | yourParsedColor)

Then set that color.

然后设置颜色。

#7


-1  

My current fix involves having a drawable without the color option. I put it inside a frame layout, and then set the background color of the frame layout object dynamically. It's still technically a 'fix,' but it's the most simple option in my opinion.

我目前的解决方案是在没有颜色选项的情况下进行绘制。我把它放在一个框架布局中,然后动态设置框架布局对象的背景颜色。从技术上来说,这仍是一种“修复”,但在我看来,这是最简单的选择。

Layout File:

布局文件:

<FrameLayout
    android:id="@+id/dateLayout"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:background="@color/SecondaryGreen">

    <ImageView
        android:id="@+id/dateBox"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@drawable/date_rectangle" />

</FrameLayout>

Date Rectangle Drawable File:

日期矩形可拉的文件:

<shape xmlns:android="http://schemas.android.com/apk/res/android" ><size android:width="50dp" android:height="50dp"/><corners android:radius="5dp"/></shape>

Dynamic Rendering:

动态呈现:

mHolder.dateLayout.setBackgroundColor(getResources().getColor(R.color.SecondaryGreen));

#8


-1  

Set GradientDrawable Shape color using hex code/value
Simply prefix 0x to hexadecimal color value.

使用十六进制代码/值简单地将前缀0x设置为十六进制颜色值。

    GradientDrawable shape =  new GradientDrawable();
    shape.setCornerRadius( 16 );
    shape.setColor(0xff33b5e5);
    ButtonStartSurvey.setBackground(shape);