So programmieren Sie Ecken programmgesteuert und legen zufällige Hintergrundfarben fest

114

Ich möchte die Ecken einer Ansicht abrunden und die Farbe der Ansicht basierend auf dem Inhalt zur Laufzeit ändern.

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

Ich hatte gehofft, ein Zeichen zu setzen und die Farbe würde sich überlappen, aber das tun sie nicht. Was auch immer ich als zweites ausführe, ist der resultierende Hintergrund.

Gibt es eine Möglichkeit, diese Ansicht programmgesteuert zu erstellen, wobei zu berücksichtigen ist, dass die Hintergrundfarbe erst zur Laufzeit festgelegt wird?

edit: Ich wechsle jetzt nur zum Testen zwischen Rot und Blau. Später kann der Benutzer die Farbe auswählen.

bearbeiten:

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
quelle
Natürlich überschreiben sich die Hintergrundfarbe und das Hintergrundbild. Was versuchst du zu erreichen? Was ist tags_rounded_corners?
Alex MDC
Könnten Sie mehr Codes anzeigen? Es sieht gut aus, daher frage ich mich, ob Sie eine Art listView verwenden oder eine vorhandene Textansicht wiederverwenden können.
Chansuk

Antworten:

210

setBackgroundColorRufen Sie stattdessen den Hintergrund zum Zeichnen auf und legen Sie seine Farbe fest:

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

Sie können auch die Polsterung in Ihrem 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
quelle
Perect answe! es hat auch mit strock funktioniert, aber können wir dies mit so etwas wie colorDrawable = resources.getDrawable (R.drawable.x_sd_circle) machen; colorDrawable.setColorFilter (color, PorterDuff.Mode.SRC_ATOP); wenn wir keine Grenze haben. Aber im Falle einer Grenze können Sie mir den PorterDuff.Mode mitteilen, damit sich die Strichfarbe nicht ändert
Akhil Dad
Wie füge ich Hintergrundfarben auch über XML hinzu?
Lenin Raj Rajasekaran
2
Wenn "v" die Textansicht ist, wird v.getBackground () "java.lang.ClassCastException: android.graphics.drawable.StateListDrawable kann nicht in android.graphics.drawable.GradientDrawable umgewandelt werden". Funktionierte dies wirklich in '13?
Sonavolob
@sonavolob du hast recht. es gibt ClassCastException
Adnan
Die perfekte Lösung! Danke dir!
Bot
124

Vollständiger programmatischer Ansatz zum Festlegen abgerundeter Ecken und zum Hinzufügen einer zufälligen Hintergrundfarbe zu einer Ansicht. Ich habe den Code nicht getestet, aber Sie haben die Idee.

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

Hier verwenden wir einen Gradienten, der gezeichnet werden kann, damit wir ihn verwenden können, GradientDrawable#setCornerRadiusda ShapeDrawableKEINE solche Methode bereitgestellt wird.

JaydeepW
quelle
13
shape.setCornerRadii (Ecken); Es ist sehr nützlich
umesh
14
Erwägen Sie die Verwendung PaintDrawableanstelle von GradientDrawable. Es unterstützt abgerundete Ecken und nur eine einzige Farbe, die geeigneter zu sein scheint als ein Farbverlauf.
Cimlman
2
Das funktioniert gut! Ich benutze es in Xamarin. var pd = new PaintDrawable(BackgroundColor); pd.SetCornerRadius(15); myView.Background = pd;
Pierre
Schöne schnelle Lösung, aber beachten Sie, dass es API Minimum Level 16
The Unknown Dev
Wie stelle ich den Eckenradius nur für eine Seite ein?
Anonymous-E
10

Ich denke, der schnellste Weg, dies zu tun, ist:

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

Sie können dies besser erreichen, indem Sie den DrawableCompat folgendermaßen verwenden :

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

Wenn Sie keinen Schlaganfall haben, können Sie verwenden

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

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

Dies ändert jedoch auch die Strichfarbe

Akhil Dad
quelle
39
Ich wollte das benutzen, aber ich habe einen Schlaganfall.
Tim Malseed
2

Hier ist ein Beispiel mit einer Erweiterung. Dies setzt voraus, dass die Ansicht dieselbe Breite und Höhe hat.

Sie müssen einen Listener für Layoutänderungen verwenden, um die Ansichtsgröße zu ermitteln. Dann können Sie dies einfach in einer solchen Ansicht aufrufenmyView.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
quelle
1

Sie können die Farbe beliebiger Elemente (Layout, Textansicht) dynamisch ändern. Versuchen Sie den folgenden Code, um die Farbe programmgesteuert im Layout festzulegen

in der Datei 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));

Erstellen Sie layout_round.xml in einem zeichnbaren Ordner

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

Layout in der Datei activity.xml

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

----other components---

</LinearLayout>

leidenschaftliche evops
quelle
1

Kopieren des Kommentars von @ cimlman in eine Antwort auf oberster Ebene für mehr Sichtbarkeit:

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

Zu Ihrer Information : ShapeDrawable(und sein Subtyp PaintDrawable) verwendet die standardmäßige intrinsische Breite und Höhe von 0. Wenn das Zeichen in Ihrem Anwendungsfall nicht angezeigt wird, müssen Sie die Abmessungen möglicherweise manuell festlegen:

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

-1ist eine magische Konstante, die angibt, dass ein Drawable keine eigene Breite und Höhe hat ( Quelle ).

Saket
quelle