2011-08-23 199 views
112

如何动态更改形状颜色?

<?xml version="1.0" encoding="utf-8"?> 
<shape xmlns:android="http://schemas.android.com/apk/res/android" 
    android:shape="rectangle"> 
    <solid 
     android:color="#FFFF00" /> 
    <padding android:left="7dp" 
     android:top="7dp" 
     android:right="7dp" 
     android:bottom="7dp" /> 
</shape> 

<TextView 
    android:background="@drawable/test" 
    android:layout_height="45dp" 
    android:layout_width="100dp" 
    android:text="Moderate" 
/> 

所以现在我想根据我从Web服务调用回信息,这种形状改变颜色。所以它可能是黄色或绿色或红色或任何取决于我从网络服务调用收到的颜色。

如何更改形状的颜色?基于这些信息?

+3

由@Couitchy方法指定'View.getBackground()'返回'GradientDrawable'而不是'ShapeDrawable'导致应用程序在运行时崩溃,原因是尝试获取引用时无效转换并以编程方式设置颜色。 [Android Shape doc](http://developer.android.com/guide/topics/resources/drawable-resource.html#Shape)指出:*编译的资源数据类型: 指向'GradientDrawable' *的资源指针。 –

回答

249

您可以修改它只是像这样

GradientDrawable bgShape = (GradientDrawable)btn.getBackground(); 
bgShape.setColor(Color.BLACK); 
+9

什么是btn.getBackground? – chobo2

+0

btn可以是您为其设置可从xml绘制的形状的任何视图。因此,您可以在该视图上使用getBackground()获取drawable并更改其颜色。 – Ronnie

+1

Hmm很难将此代码转换为monodroid ShapeDrawable bgShape =(ShapeDrawable)Resources.GetDrawable(Resource.Drawable.test);只是崩溃 – chobo2

10

您可以用Java构建自己的形状。 我这样做是为iPhone像页的Controler和油漆的形状在Java中:

/** 
* Builds the active and inactive shapes/drawables for the page control 
*/ 
private void makeShapes() { 

    activeDrawable = new ShapeDrawable(); 
    inactiveDrawable = new ShapeDrawable(); 
    activeDrawable.setBounds(0, 0, (int) mIndicatorSize, 
      (int) mIndicatorSize); 
    inactiveDrawable.setBounds(0, 0, (int) mIndicatorSize, 
      (int) mIndicatorSize); 

    int i[] = new int[2]; 
    i[0] = android.R.attr.textColorSecondary; 
    i[1] = android.R.attr.textColorSecondaryInverse; 
    TypedArray a = this.getTheme().obtainStyledAttributes(i); 

    Shape s1 = new OvalShape(); 
    s1.resize(mIndicatorSize, mIndicatorSize); 
    Shape s2 = new OvalShape(); 
    s2.resize(mIndicatorSize, mIndicatorSize); 

    ((ShapeDrawable) activeDrawable).getPaint().setColor(
      a.getColor(0, Color.DKGRAY)); 
    ((ShapeDrawable) inactiveDrawable).getPaint().setColor(
      a.getColor(1, Color.LTGRAY)); 

    ((ShapeDrawable) activeDrawable).setShape(s1); 
    ((ShapeDrawable) inactiveDrawable).setShape(s2); 
} 

希望这会有所帮助。 Greez费边

51

对于我来说,它坠毁因为getBackground返回GradientDrawable而不是ShapeDrawable的。

所以我修改了它这样的:

((GradientDrawable)someView.getBackground()).setColor(someColor); 
+1

感谢工作很好:) –

5
LayerDrawable bgDrawable = (LayerDrawable) button.getBackground(); 
    final GradientDrawable shape = (GradientDrawable) 
      bgDrawable.findDrawableByLayerId(R.id.round_button_shape); 
    shape.setColor(Color.BLACK); 
31

这对我的作品,最初的XML资源:上述的

example.setBackgroundResource(R.drawable.myshape); 
GradientDrawable gd = (GradientDrawable) example.getBackground().getCurrent(); 
gd.setColor(Color.parseColor("#000000")); 
gd.setCornerRadii(new float[]{30, 30, 30, 30, 0, 0, 30, 30}); 
gd.setStroke(2, Color.parseColor("#00FFFF"), 5, 6); 

结果:http://i.stack.imgur.com/hKUR7.png

+0

这是正确的答案。上面提到的答案都不适合我。我在这两个方面都得到了例外。 –

2

这解决方案为我使用android sdk v19:

//get the image button by id 
ImageButton myImg = (ImageButton) findViewById(R.id.some_id); 

//get drawable from image button 
GradientDrawable drawable = (GradientDrawable) myImg.getDrawable(); 

//set color as integer 
//can use Color.parseColor(color) if color is a string 
drawable.setColor(color) 
2

如果你有一个这样的ImageView的:

<ImageView 
    android:id="@+id/color_button" 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:layout_marginRight="10dp" 
    android:src="@drawable/circle_color"/> 

这给它的可绘制形状src时,可以使用此代码来改变形状的颜色:

ImageView iv = (ImageView)findViewById(R.id.color_button); 
GradientDrawable bgShape = (GradientDrawable)iv.getDrawable(); 
bgShape.setColor(Color.BLACK); 
5

也许别人需要改变XML中的颜色,而不需要像我需要的那样创建多个drawable。然后创建一个没有颜色的可绘制圆,然后为ImageView指定backgroundTint。

circle.xml

<?xml version="1.0" encoding="utf-8"?> 
<shape 
    xmlns:android="http://schemas.android.com/apk/res/android" 
    android:shape="oval"> 
</shape> 

而在你布局

<ImageView 
    android:layout_width="50dp" 
    android:layout_height="50dp" 
    android:background="@drawable/circle" 
    android:backgroundTint="@color/red"/> 

编辑:

有一个bug对于这种方法,防止它工作在Android Loll上ipop 5.0(API级别21)。但已在新版本中修复。

1

我的形状XML:

<?xml version="1.0" encoding="utf-8"?> 
<shape xmlns:android="http://schemas.android.com/apk/res/android"> 
<solid android:color="@android:color/transparent" /> 
<stroke android:width="0.5dp" android:color="@android:color/holo_green_dark"/> 
</shape> 

我的活动XML:

<?xml version="1.0" encoding="utf-8"?> 
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android" 
xmlns:app="http://schemas.android.com/apk/res-auto" 
xmlns:tools="http://schemas.android.com/tools" 
android:layout_width="match_parent" 
android:layout_height="match_parent" 
android:fitsSystemWindows="true" 
tools:context="cn.easydone.test.MainActivity"> 

<android.support.design.widget.AppBarLayout 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content" 
    android:theme="@style/AppTheme.AppBarOverlay"> 

    <android.support.v7.widget.Toolbar 
     android:id="@+id/toolbar" 
     android:layout_width="match_parent" 
     android:layout_height="?attr/actionBarSize" 
     android:background="?attr/colorPrimary" 
     app:popupTheme="@style/AppTheme.PopupOverlay" /> 
    <TextView 
     android:id="@+id/test_text" 
     android:background="@drawable/bg_stroke_dynamic_color" 
     android:padding="20dp" 
     android:text="asdasdasdasd" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content"/> 

</android.support.design.widget.AppBarLayout> 

<android.support.v7.widget.RecyclerView 
    android:id="@+id/recycler_view" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:padding="10dp" 
    android:clipToPadding="false" 
    app:layout_behavior="@string/appbar_scrolling_view_behavior" /> 

我的活动的java:

TextView testText = (TextView) findViewById(R.id.test_text); 
((GradientDrawable)testText.getBackground()).setStroke(10,Color.BLACK); 

效果图: result

3

circle.xml(绘制)

<?xml version="1.0" encoding="utf-8"?> 
<shape 
xmlns:android="http://schemas.android.com/apk/res/android" 
android:shape="rectangle"> 

<solid 
    android:color="#000"/> 

<size 
    android:width="10dp" 
    android:height="10dp"/> 
</shape> 

布局

<ImageView 
     android:id="@+id/circleColor" 
     android:layout_width="15dp" 
     android:layout_height="15dp" 
     android:textSize="12dp" 
     android:layout_gravity="center" 
     android:layout_marginLeft="10dp" 
     android:background="@drawable/circle"/> 

在活动

circleColor = (ImageView) view.findViewById(R.id.circleColor); 
    int color = Color.parseColor("#00FFFF"); 
    ((GradientDrawable)circleColor.getBackground()).setColor(color); 
0

我尝试罗尼的回答,我的应用程序崩溃。然后我检查我的drawable xml。它看起来像这样:

<selector >...</selector> 

。我把它改为:(也改变属性)

<shape> ... </shape> 

它的工作原理。

对于那些遇到同样问题的人。