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

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


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 colorgradientDrawableChecked.setColor(Color.BLUE);gradientDrawableUnChecked.setColor(Color.RED);//strokegradientDrawableChecked.setStroke(1, Color.RED);gradientDrawableUnChecked.setStroke(1, Color.BLUE);


I needed a way to change the stroke color of any GradientDrawable without knowing the width of the stroke. My goal was to do this using Drawable.setTint. I had to add a transparent solid element to my shape xml to get it to work:

<!-- 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.ktsetBackgroundResource(R.drawable.stroke_background)// Set the color of your strokedrawable.setTint(Color.BLUE)

In your case, since you have both a solid and stroke, then you'll need to use a layer-list, where the stroke is added AFTER the solid (so that it's drawn on top). This will let you set different colors on the solid and the stroke without knowing in advance what the stroke width is:

<!-- 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.ktsetBackgroundResource(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)}


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