I need to change the stroke color to a user define

2019-01-16 10:08发布

问题:

I need to change the stroke color from the app. The user is able to change the background color so I need to also let them change the stroke (outline) of the button. As its is already set in the drawable (sample below) I have not found a way to change this. Seems like all of the other questions like this just said to use the XML file.... but that doesnt let me make it dynamic. Thank you for any help!

I need to change the stroke color to a user defined color. Nothing to do with the state.

<?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>

回答1:

1. If you have drawable file for a "view" like this

<?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>

Then you can change
a. Stroke color :

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


b. Solid color :

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

2. If you have drawable file for a "view" like this

<?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>

Then you can change the individual item attributes by taking separate drawable objects by there positions.

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

now to change stroke or solid color :

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

//stroke
gradientDrawableChecked.setStroke(1, Color.RED);
gradientDrawableUnChecked.setStroke(1, Color.BLUE);


回答2:

Perhaps they are referring to Color State Lists which allows you to change the color based on whether the button was pressed/focused/enabled/etc



回答3:

Try using StateLists (as opposed to ColorStateList). Take a look: http://developer.android.com/guide/topics/resources/drawable-resource.html#StateList

You can also create a ShapeDrawable (or a RoundRectShape in your example) programmatically, and then call the button's setBackgroundDrawable



回答4:

I answered a similar question in Change shape border color at runtime

Its like the same solution proposed by f20k but in my case the drawable was a GradientDrawable instead of a ShapeDrawable.

see if it works...



回答5:

Please look at the LayerDrawable because it created from your XML and used at runtime.

Here is a Demo Example:

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

You can modify it at runtime like:

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