76

我需要从应用程序更改笔触颜色。用户可以更改背景颜色,因此我还需要让他们更改按钮的笔触(轮廓)。由于它已经在可绘制对象(下面的示例)中设置,我还没有找到改变它的方法。似乎像这样的所有其他问题都只是说要使用 XML 文件....但这并没有让我让它变得动态。感谢您的任何帮助!

我需要将笔触颜色更改为用户定义的颜色。与国家无关。

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

    <solid android:color="#ffffffff"/>    
      <stroke
                android:width="3dp"
                android:color="@color/Dim_Gray" />  <<<<--- This is what I need to change


    <padding android:left="10dp"
             android:top="10dp"
             android:right="10dp"
             android:bottom="10dp"
             /> 

    <corners android:bottomRightRadius="12dp" android:bottomLeftRadius="12dp" 
     android:topLeftRadius="12dp" android:topRightRadius="12dp"/> 

</shape>
4

6 回答 6

229

1.如果您有这样的“视图”的可绘制文件

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

<corners android:radius="5dp" />

<solid android:color="@android:color/white" />

<stroke
    android:width="3px"
    android:color="@color/blue" />

</shape>

然后就可以换
一个了。描边颜色:

GradientDrawable drawable = (GradientDrawable)view.getBackground();
drawable.setStroke(3, Color.RED); // set stroke width and stroke color 


湾。纯色 :

GradientDrawable drawable = (GradientDrawable)view.getBackground();
drawable.setColor(Color.RED); // set solid color

2.如果你有这样的“视图”的可绘制文件

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_checked="true" android:id="@+id/buttonSelected">
        <shape>
            <solid android:color="@color/blue" />
            <stroke android:width="1px" android:color="@color/blue" />
        </shape>
    </item>
    <item android:state_checked="false" android:id="@+id/buttonNotSelected">
        <shape android:shape="rectangle">
            <solid android:color="@color/white" />
            <stroke android:width="1px" android:color="@color/blue" />
        </shape>
    </item>
</selector>

然后,您可以通过在该位置获取单独的可绘制对象来更改单个项目属性。

StateListDrawable drawable = (StateListDrawable)view.getBackground();
DrawableContainerState dcs = (DrawableContainerState)drawable.getConstantState();
Drawable[] drawableItems = dcs.getChildren();
GradientDrawable gradientDrawableChecked = (GradientDrawable)drawableItems[0]; // item 1 
GradientDrawable gradientDrawableUnChecked = (GradientDrawable)drawableItems[1]; // item 2

现在改变描边或纯色:

//solid color
gradientDrawableChecked.setColor(Color.BLUE);
gradientDrawableUnChecked.setColor(Color.RED);

//stroke
gradientDrawableChecked.setStroke(1, Color.RED);
gradientDrawableUnChecked.setStroke(1, Color.BLUE);
于 2015-03-23T06:49:53.233 回答
24

我需要一种在GradientDrawable不知道笔画宽度的情况下更改任何笔画颜色的方法。我的目标是使用Drawable.setTint. 我必须在我的 xml 中添加一个透明solid元素shape才能让它工作:

<!-- stroke_background.xml -->
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">
    <stroke
        android:width="4dp"
        android:color="@android:color/white" />
    <!-- Need transparent solid to get tint applied to only the stroke -->
    <solid android:color="@android:color/transparent"/>
</shape>
// StrokeView.kt
setBackgroundResource(R.drawable.stroke_background)
// Set the color of your stroke
drawable.setTint(Color.BLUE)

在您的情况下,由于您同时拥有 asolidstroke,因此您需要使用 a layer-list,在实体之后添加笔划(以便将其绘制在顶部)。这将让您在实体和笔划上设置不同的颜色,而无需事先知道笔划宽度是多少:

<!-- stroke_solid_background.xml -->
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@drawable/solid_background" />
    <item android:drawable="@drawable/stroke_background" />
</layer-list>
// StrokeSolidView.kt
setBackgroundResource(R.drawable.stroke_solid_background)
(drawable as LayerDrawable).apply {
    // Set the color of your solid
    getDrawable(0).setTint(Color.GREEN)
    // Set the color of your stroke
    getDrawable(1).setTint(Color.BLUE)
}
于 2019-02-07T04:43:30.367 回答
3

请查看LayerDrawable,因为它是从您的 XML 创建并在运行时使用的。

这是一个演示示例:

<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item>
        <shape android:shape="rectangle" >
            <solid android:color="@android:color/transparent" />
        </shape>
    </item>
    <item android:id="@+id/itemId" android:top="-4dp" android:right="-4dp" android:left="-4dp">
        <shape>
            <solid android:color="@android:color/transparent"/>
            <stroke
                android:width="1.5dp"
                android:color="#06C1D7" >
            </stroke>
            <padding
                android:bottom="-2dp"/>

        </shape>
    </item>
</layer-list>

您可以在运行时修改它,例如:

 LayerDrawable layerDrawable = (LayerDrawable) getResources()
                .getDrawable(R.drawable.only_one_bottom_line);
        GradientDrawable gradientDrawable = (GradientDrawable) layerDrawable.findDrawableByLayerId(R.id.itemId);
        int px = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 1.5f, getResources().getDisplayMetrics());

        gradientDrawable.setStroke(px, getResources().getColor(R.color.theme_color));
        tv_select_city_name.setBackground(layerDrawable);
于 2018-07-24T06:47:05.283 回答
0

我在运行时更改形状边框颜色中回答了类似的问题

它类似于 f20k 提出的相同解决方案,但在我的情况下,drawable 是 GradientDrawable 而不是 ShapeDrawable。

看看它是否有效...

于 2013-02-23T19:53:50.913 回答
0

尝试使用 StateLists(而不是 ColorStateList)。看看:http: //developer.android.com/guide/topics/resources/drawable-resource.html#StateList

您还可以以编程方式创建一个ShapeDrawable(或RoundRectShape您的示例中的一个),然后调用按钮的setBackgroundDrawable

于 2011-01-23T09:59:50.177 回答
-1

也许他们指的是颜色状态列表,它允许您根据按钮是否被按下/聚焦/启用/等来更改颜色

于 2011-01-23T06:56:07.150 回答