Wie kann man die Formfarbe dynamisch ändern?


136

ich habe

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
   android:shape="rectangle">
    <solid
       android:color="#FFFF00" />
    <padding android:left="7dp"
        android:top="7dp"
        android:right="7dp"
        android:bottom="7dp" />
</shape>

<TextView
    android:background="@drawable/test"
    android:layout_height="45dp"
    android:layout_width="100dp"
    android:text="Moderate"
/>

Jetzt möchte ich, dass diese Form ihre Farben basierend auf Informationen ändert, die ich von einem Webdienstanruf zurückerhalte. Es könnte also vielleicht gelb oder grün oder rot oder was auch immer sein, abhängig von der Farbe, die ich vom Web-Service-Anruf erhalte.

Wie kann ich die Farbe der Form ändern? Basierend auf diesen Informationen?


3
Wie von der @ Couitchy-Methode festgelegt, wird View.getBackground()a GradientDrawableund nicht a zurückgegeben, ShapeDrawablewodurch die App zur Laufzeit abstürzt, da beim Versuch, die Referenz abzurufen und die Farbe programmgesteuert festzulegen, eine ungültige Besetzung vorliegt . [Android Shape doc] ( developer.android.com/guide/topics/resources/… ) gibt an: COMPILED RESOURCE DATATYPE: Ressourcenzeiger auf aGradientDrawable .
Luis Quijada

Antworten:


300

Sie können es einfach so ändern

GradientDrawable bgShape = (GradientDrawable)btn.getBackground();
bgShape.setColor(Color.BLACK);

9
Was ist btn.getBackground?
Chobo2

16
Ich bekomme, java.lang.ClassCastException: android.graphics.drawable.GradientDrawable cannot be cast to android.graphics.drawable.ShapeDrawablewenn ich diesen Vorschlag versuche.
Prolink007

2
Funktioniert nicht. Sie erhalten einen Besetzungsfehler. Benötigt einen Fix oder eine andere Antwort akzeptiert
ndgreen

6
Das funktioniert gut. Die vorherigen Kommentare sind veraltet, da die Antwort bearbeitet wurde!
W3hri

4
sollte GradientDrawable verwenden bgShape = (GradientDrawable) btn.getBackground (). getCurrent ();
Naveed148

60

Für mich stürzte es ab, weil getBackgroundein GradientDrawablestatt ein zurückgegeben wurde ShapeDrawable.

Also habe ich es so modifiziert:

((GradientDrawable)someView.getBackground()).setColor(someColor);

42

Dies funktioniert bei mir mit einer anfänglichen XML-Ressource:

example.setBackgroundResource(R.drawable.myshape);
GradientDrawable gd = (GradientDrawable) example.getBackground().getCurrent();
gd.setColor(Color.parseColor("#000000"));
gd.setCornerRadii(new float[]{30, 30, 30, 30, 0, 0, 30, 30});
gd.setStroke(2, Color.parseColor("#00FFFF"), 5, 6);

Ergebnis der obigen Angaben : http://i.stack.imgur.com/hKUR7.png


Dies ist die richtige Antwort. Beide oben genannten Antworten wurden für mich nicht bearbeitet. Ich bekomme eine Ausnahme von beiden.
Sanal Varghese

10

Sie können Ihre eigenen Formen in Java erstellen. Ich habe dies für ein iPhone wie Page Controler gemacht und die Formen in Java gemalt:

/**
 * Builds the active and inactive shapes / drawables for the page control
 */
private void makeShapes() {

    activeDrawable = new ShapeDrawable();
    inactiveDrawable = new ShapeDrawable();
    activeDrawable.setBounds(0, 0, (int) mIndicatorSize,
            (int) mIndicatorSize);
    inactiveDrawable.setBounds(0, 0, (int) mIndicatorSize,
            (int) mIndicatorSize);

    int i[] = new int[2];
    i[0] = android.R.attr.textColorSecondary;
    i[1] = android.R.attr.textColorSecondaryInverse;
    TypedArray a = this.getTheme().obtainStyledAttributes(i);

    Shape s1 = new OvalShape();
    s1.resize(mIndicatorSize, mIndicatorSize);
    Shape s2 = new OvalShape();
    s2.resize(mIndicatorSize, mIndicatorSize);

    ((ShapeDrawable) activeDrawable).getPaint().setColor(
            a.getColor(0, Color.DKGRAY));
    ((ShapeDrawable) inactiveDrawable).getPaint().setColor(
            a.getColor(1, Color.LTGRAY));

    ((ShapeDrawable) activeDrawable).setShape(s1);
    ((ShapeDrawable) inactiveDrawable).setShape(s2);
}

hoffe das hilft. Griechischer Fabian


7

Vielleicht muss jemand anderes die Farbe im XML ändern, ohne mehrere Drawables zu erstellen, wie ich es brauchte. Machen Sie dann einen Kreis ohne Farbe zeichnbar und geben Sie backgroundTint für die ImageView an.

circle.xml

<?xml version="1.0" encoding="utf-8"?>
<shape
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="oval">
</shape>

Und in Ihrem Layout :

<ImageView
    android:layout_width="50dp"
    android:layout_height="50dp"
    android:background="@drawable/circle"
    android:backgroundTint="@color/red"/>

Bearbeiten:

Es gibt einen Fehler in Bezug auf diese Methode, der verhindert, dass sie unter Android Lollipop 5.0 (API-Level 21) funktioniert. Wurden aber in neueren Versionen behoben.


5
    LayerDrawable bgDrawable = (LayerDrawable) button.getBackground();
    final GradientDrawable shape = (GradientDrawable)
            bgDrawable.findDrawableByLayerId(R.id.round_button_shape);
    shape.setColor(Color.BLACK);

Wo soll round_button_shape in der Form-XML-Datei definiert werden?
Jayesh

5

circle.xml (zeichnbar)

<?xml version="1.0" encoding="utf-8"?>
<shape
xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">

<solid
    android:color="#000"/>

<size
    android:width="10dp"
    android:height="10dp"/>
</shape>

Layout

<ImageView
      android:id="@+id/circleColor"
      android:layout_width="15dp"
       android:layout_height="15dp"
      android:textSize="12dp"
       android:layout_gravity="center"
       android:layout_marginLeft="10dp"
      android:background="@drawable/circle"/>

in Aktivität

   circleColor = (ImageView) view.findViewById(R.id.circleColor);
   int color = Color.parseColor("#00FFFF");
   ((GradientDrawable)circleColor.getBackground()).setColor(color);

Keine perfekte, aber sie hat mir geholfen, die Lösung zu finden.
Rakesh Yadav

2

Diese Lösung funktionierte bei mir mit dem Android SDK V19:

//get the image button by id
ImageButton myImg = (ImageButton) findViewById(R.id.some_id);

//get drawable from image button
GradientDrawable drawable = (GradientDrawable) myImg.getDrawable();

//set color as integer
//can use Color.parseColor(color) if color is a string
drawable.setColor(color)

2

Wenn Sie eine Bildansicht wie diese haben:

   <ImageView
    android:id="@+id/color_button"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_marginRight="10dp"
    android:src="@drawable/circle_color"/>

Mit diesem Code können Sie die Farbe der Form ändern:

ImageView iv = (ImageView)findViewById(R.id.color_button);
GradientDrawable bgShape = (GradientDrawable)iv.getDrawable();
bgShape.setColor(Color.BLACK);

1

Meine Form xml:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid  android:color="@android:color/transparent" />
<stroke android:width="0.5dp" android:color="@android:color/holo_green_dark"/>
</shape>

Meine Aktivität xml:

<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:context="cn.easydone.test.MainActivity">

<android.support.design.widget.AppBarLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:theme="@style/AppTheme.AppBarOverlay">

    <android.support.v7.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"
        android:background="?attr/colorPrimary"
        app:popupTheme="@style/AppTheme.PopupOverlay" />
    <TextView
        android:id="@+id/test_text"
        android:background="@drawable/bg_stroke_dynamic_color"
        android:padding="20dp"
        android:text="asdasdasdasd"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>

</android.support.design.widget.AppBarLayout>

<android.support.v7.widget.RecyclerView
    android:id="@+id/recycler_view"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="10dp"
    android:clipToPadding="false"
    app:layout_behavior="@string/appbar_scrolling_view_behavior" />

Meine Aktivität Java:

 TextView testText = (TextView) findViewById(R.id.test_text);
 ((GradientDrawable)testText.getBackground()).setStroke(10,Color.BLACK);

Ergebnisbild: Ergebnis


1

Der einfachste Weg, die Form mit dem Radius zu füllen, ist:

XML:

<TextView
    android:id="@+id/textView"
    android:background="@drawable/test"
    android:layout_height="45dp"
    android:layout_width="100dp"
    android:text="Moderate"/>

Java:

(textView.getBackground()).setColorFilter(Color.parseColor("#FFDE03"), PorterDuff.Mode.SRC_IN);

0

Ich versuche Ronnies Antwort und meine App stürzte ab. Dann überprüfe ich meine zeichnbare XML. Es sieht aus wie das:

<selector >...</selector>

. Ich habe es folgendermaßen geändert: (auch Attribute geändert)

<shape> ... </shape>

Es klappt.

Für diejenigen, die auf das gleiche Problem stoßen.


0

drawable_rectangle.xml

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">

    <solid android:color="@android:color/transparent" />

    <stroke
        android:width="1dp"
        android:color="#9f9f9f" />

    <corners
        android:bottomLeftRadius="5dp"
        android:bottomRightRadius="5dp"
        android:topLeftRadius="5dp"
        android:topRightRadius="5dp" />

</shape>

Textübersicht

<androidx.appcompat.widget.AppCompatTextView
    android:id="@+id/textView"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:background="@drawable/drawable_rectangle"
    android:gravity="center"
    android:padding="10dp"
    android:text="Status"
    android:textColor="@android:color/white"
    android:textSize="20sp" />


public static void changeRectangleColor(View view, int color) {
    ((GradientDrawable) view.getBackground()).setStroke(1, color);
}    

changeRectangleColor(textView, ContextCompat.getColor(context, R.color.colorAccent));

0

Sie können dazu einen Bindungsadapter (Kotlin) verwenden . Erstellen Sie eine Bindungsadapterklasse mit dem Namen ChangeShapeColor wie unten

@BindingAdapter("shapeColor")

// Method to load shape and set its color 

fun loadShape(textView: TextView, color: String) {
// first get the drawable that you created for the shape 
val mDrawable = ContextCompat.getDrawable(textView.context, 
R.drawable.language_image_bg)
val  shape =   mDrawable as (GradientDrawable)
// use parse color method to parse #34444 to the int 
shape.setColor(Color.parseColor(color))
 }

Erstellen Sie eine zeichnbare Form im Ordner res / drawable. Ich habe einen Kreis erstellt

<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval" >
<solid android:color="#anyColorCode"/>

<size
    android:width="@dimen/dp_16"
    android:height="@dimen/dp_16"/>
</shape>

Beziehen Sie sich schließlich auf Ihre Ansicht

  <TextView>
   .........
  app:shapeColor="@{modelName.colorString}"
 </Textview>
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.