web-dev-qa-db-fra.com

Je dois changer la couleur de trait en une couleur définie par l'utilisateur. Rien à voir avec l'état

Je dois changer la couleur de trait de l'application. L'utilisateur peut modifier la couleur d'arrière-plan. Je dois donc lui permettre de modifier le contour du bouton. Comme il est déjà défini dans le dessin (exemple ci-dessous), je n’ai pas trouvé le moyen de changer cela. On dirait que toutes les autres questions comme celle-ci viennent d'utiliser le fichier XML ... mais cela ne me laisse pas le rendre dynamique. Merci pour toute aide!

Je dois changer la couleur de trait pour une couleur définie par l'utilisateur. Rien à voir avec l'état.

<?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>
42
Mark Worsnop

1. Si vous avez un fichier dessinable pour une "vue" comme celle-ci

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

Ensuite, vous pouvez changer
une. Couleur de trait:  

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


b. Couleur unie :

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

2. Si vous avez un fichier dessinable pour une "vue" comme celle-ci

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

Ensuite, vous pouvez changer les éléments individuels item / en prenant séparer les objets pouvant être dessinés par leurs 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

maintenant pour changer le trait ou la couleur unie:  

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

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

J'avais besoin d'un moyen de changer la couleur du trait d'une variable GradientDrawable sans connaître la largeur du trait. Mon objectif était de faire cela en utilisant Drawable.setTint. Je devais ajouter un élément solid transparent à mon shape xml pour que cela fonctionne:

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

Dans votre cas, étant donné que vous avez à la fois une solid et une stroke, vous devrez alors utiliser un layer-list, dans lequel le trait est ajouté APRÈS le solide (pour qu'il soit tracé au-dessus). Cela vous permettra de définir différentes couleurs sur le solide et le trait sans savoir à l'avance quelle est la largeur du trait:

<!-- 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)
}
0
iamreptar

J'ai répondu à une question similaire dans Changer la couleur de la bordure de la forme lors de l'exécution

Cela ressemble à la même solution proposée par f20k, mais dans mon cas, le dessinable était GradientDrawable au lieu de ShapeDrawable.

voir si ça marche ...

0
rodalves

Veuillez regarder LayerDrawable car il a été créé à partir de votre XML et utilisé à l'exécution.

Voici un exemple de démonstration:

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

Vous pouvez le modifier au moment de l'exécution comme:

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

Peut-être font-ils référence à Color State Lists qui vous permet de modifier la couleur selon que le bouton a été appuyé/mis au point/activé/etc

0
f20k

Essayez d’utiliser StateLists (par opposition à ColorStateList). Jetez un coup d'oeil: http://developer.Android.com/guide/topics/resources/drawable-resource.html#StateList

Vous pouvez également créer une ShapeDrawable (ou une RoundRectShape dans votre exemple) par programme, puis appeler le bouton setBackgroundDrawable.

0
Lior