Comment arrondir les coins par programmation et définir des couleurs d'arrière-plan aléatoires

114

Je voudrais arrondir les coins d'une vue et également changer la couleur de la vue en fonction du contenu au moment de l'exécution.

TextView v = new TextView(context);
v.setText(tagsList.get(i));
if(i%2 == 0){
    v.setBackgroundColor(Color.RED);
}else{
    v.setBackgroundColor(Color.BLUE);
}

v.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT));
v.setPadding(twoDP, twoDP, twoDP, twoDP);               
v.setBackgroundResource(R.drawable.tags_rounded_corners);

J'espérais que définir un dessin et une couleur se chevaucheraient, mais ce n'est pas le cas. Celui que j'exécute en second est le fond résultant.

Existe-t-il un moyen de créer cette vue par programme, en gardant à l'esprit que la couleur d'arrière-plan ne sera pas décidée avant l'exécution?

edit: Je passe uniquement du rouge au bleu pour le test. Plus tard, la couleur pourra être choisie par l'utilisateur.

Éditer:

tags_rounded_corners.xml:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" >
    <corners 
         android:bottomRightRadius="2dp" 
         android:bottomLeftRadius="2dp" 
         android:topLeftRadius="2dp" 
         android:topRightRadius="2dp"/>
</shape>
John Moffitt
la source
Bien sûr, la couleur d'arrière-plan et l'image d'arrière-plan se remplacent. Qu'essayez-vous de réaliser? Qu'est-ce que c'est tags_rounded_corners?
Alex MDC
Pouvez-vous montrer plus de codes? Cela a l'air bien, je me demande donc que vous puissiez utiliser une sorte de listView ou réutiliser une vue de texte existante.
Chansuk

Réponses:

211

Au lieu de setBackgroundColor, récupérez l'arrière-plan dessinable et définissez sa couleur:

v.setBackgroundResource(R.drawable.tags_rounded_corners);

GradientDrawable drawable = (GradientDrawable) v.getBackground();
if (i % 2 == 0) {
  drawable.setColor(Color.RED);
} else {
  drawable.setColor(Color.BLUE);
}

En outre, vous pouvez définir le remplissage dans votre tags_rounded_corners.xml:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
  <corners android:radius="4dp" />
  <padding
    android:top="2dp"
    android:left="2dp"
    android:bottom="2dp"
    android:right="2dp" />
</shape> 
chiuki
la source
Parfait, réponds! cela fonctionnait aussi avec strock, mais pouvons-nous faire cela en utilisant quelque chose comme colorDrawable = resources.getDrawable (R.drawable.x_sd_circle); colorDrawable.setColorFilter (couleur, PorterDuff.Mode.SRC_ATOP); si nous n'avons pas de frontière. Mais en cas de bordure, pouvez-vous me faire savoir le mode PorterDuff.Mode pour que la couleur du trait ne change pas
Akhil Dad
Comment ajouter également une couleur de fond via XML?
Lenin Raj Rajasekaran
2
Si "v" est le TextView, v.getBackground () convertira "java.lang.ClassCastException: android.graphics.drawable.StateListDrawable ne peut pas être converti en android.graphics.drawable.GradientDrawable" Cela fonctionnait-il vraiment en 2013?
sonavolob
@sonavolob vous avez raison. il donne ClassCastException
Adnan
La solution parfaite! Je vous remercie!
Bot
124

Approche programmatique totale pour définir des coins arrondis et ajouter une couleur d'arrière-plan aléatoire à une vue. Je n'ai pas testé le code, mais vous voyez l'idée.

 GradientDrawable shape =  new GradientDrawable();
 shape.setCornerRadius( 8 );

 // add some color
 // You can add your random color generator here
 // and set color
 if (i % 2 == 0) {
  shape.setColor(Color.RED);
 } else {
  shape.setColor(Color.BLUE);
 }

 // now find your view and add background to it
 View view = (LinearLayout) findViewById( R.id.my_view );
 view.setBackground(shape);

Ici, nous utilisons gradient drawable afin que nous puissions utiliser GradientDrawable#setCornerRadiuscar ShapeDrawableNE fournit PAS une telle méthode.

JaydeepW
la source
13
shape.setCornerRadii (coins); son très utile
umesh
14
Pensez à utiliser PaintDrawableau lieu de GradientDrawable. Il prend en charge les coins arrondis et juste une seule couleur qui semble être plus appropriée qu'un dégradé.
Cimlman
2
Cela fonctionne bien! Je l'utilise dans Xamarin. var pd = new PaintDrawable(BackgroundColor); pd.SetCornerRadius(15); myView.Background = pd;
Pierre
Belle solution rapide, mais notez qu'elle nécessite API Niveau minimum 16
The Unknown Dev
comment définir le rayon du coin juste pour un côté?
Anonymous-E
10

Je pense que le moyen le plus rapide d'y parvenir est:

GradientDrawable gradientDrawable = new GradientDrawable(
            GradientDrawable.Orientation.TOP_BOTTOM, //set a gradient direction 
            new int[] {0xFF757775,0xFF151515}); //set the color of gradient
gradientDrawable.setCornerRadius(10f); //set corner radius

//Apply background to your view
View view = (RelativeLayout) findViewById( R.id.my_view );
if(Build.VERSION.SDK_INT>=16)
     view.setBackground(gradientDrawable);
else view.setBackgroundDrawable(gradientDrawable);    
Nolesh
la source
9

Vous pouvez mieux y parvenir en utilisant DrawableCompat comme ceci:

Drawable backgroundDrawable = view.getBackground();             
DrawableCompat.setTint(backgroundDrawable, newColor);
Alécio Carvalho
la source
5

Si vous n'avez pas d'AVC, vous pouvez utiliser

colorDrawable = resources.getDrawable(R.drawable.x_sd_circle); 

colorDrawable.setColorFilter(color, PorterDuff.Mode.SRC_ATOP);

mais cela changera également la couleur du trait

Papa Akhil
la source
39
J'allais l'utiliser, mais j'ai un accident vasculaire cérébral.
Tim Malseed
2

Voici un exemple utilisant une extension. Cela suppose que la vue a la même largeur et hauteur.

Besoin d'utiliser un écouteur de changement de disposition pour obtenir la taille de la vue. Ensuite, vous pouvez simplement appeler cela sur une vue comme celle-cimyView.setRoundedBackground(Color.WHITE)

fun View.setRoundedBackground(@ColorInt color: Int) {
    addOnLayoutChangeListener(object: View.OnLayoutChangeListener {
        override fun onLayoutChange(v: View?, left: Int, top: Int, right: Int, bottom: Int, oldLeft: Int, oldTop: Int, oldRight: Int, oldBottom: Int) {

            val shape = GradientDrawable()
            shape.cornerRadius = measuredHeight / 2f
            shape.setColor(color)

            background = shape

            removeOnLayoutChangeListener(this)
        }
    })
}
Markymark
la source
1

Vous pouvez modifier dynamiquement la couleur de tous les éléments (mise en page, vue de texte). Essayez le code ci-dessous pour définir la couleur par programmation dans la mise en page

dans le fichier activity.java


String quote_bg_color = "#FFC107"
quoteContainer= (LinearLayout)view.findViewById(R.id.id_quotecontainer);
quoteContainer.setBackgroundResource(R.drawable.layout_round);
GradientDrawable drawable = (GradientDrawable) quoteContainer.getBackground();
drawable.setColor(Color.parseColor(quote_bg_color));

créer layout_round.xml dans un dossier dessinable

<?xml version="1.0" encoding="UTF-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
    <solid android:color="@color/colorPrimaryLight"/>
    <stroke android:width="0dp" android:color="#B1BCBE" />
    <corners android:radius="10dp"/>
    <padding android:left="0dp" android:top="0dp" android:right="0dp" android:bottom="0dp" />
</shape>

mise en page dans le fichier activity.xml

<LinearLayout
        android:id="@+id/id_quotecontainer"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical">

----other components---

</LinearLayout>

passionné
la source
1

Copie du commentaire de @ cimlman dans une réponse de premier niveau pour plus de visibilité:

PaintDrawable(Color.CYAN).apply {
  setCornerRadius(24f)
}

FYI: ShapeDrawable(et son sous-type, PaintDrawable) utilise la largeur intrinsèque par défaut et la hauteur de 0. Si le dessinable n'apparaît pas dans votre cas d'utilisation, vous devrez peut-être définir les dimensions manuellement:

PaintDrawable(Color.CYAN).apply {
  intrinsicWidth = -1
  intrinsicHeight = -1
  setCornerRadius(24f)
}

-1est une constante magique qui indique qu'un Drawable n'a pas de largeur et de hauteur intrinsèques qui lui sont propres ( Source ).

Saket
la source