So ändern Sie die Hintergrundfarbe der CardView programmgesteuert

Gibt es einen Grund, warum Google sich entschieden, nicht zu machen, eine Methode, um dynamisch die Hintergrundfarbe einer CardView?

Geschnippelt hier
So ändern Sie die Hintergrundfarbe der CardView programmgesteuert


ABHILFE

Den einfachen Zeile code @Justin Powell vorgeschlagene funktioniert bei mir nicht. Auf Android 5.0 ist. Aber es hat mich in die richtige Richtung.

Diesem code (MyRoundRectDrawableWithShadow wird eine Kopie der diese)

        card.setBackgroundDrawable(new MyRoundRectDrawableWithShadow(context.getResources(),
                color,
                card.getRadius(),
                card.getCardElevation(),
                card.getMaxCardElevation()));

... gab mir diese Fehlermeldung,

java.lang.NullPointerException: Attempt to invoke interface method 'void com.example.app.MyRoundRectDrawableWithShadow$RoundRectHelper.drawRoundRect(android.graphics.Canvas, android.graphics.RectF, float, android.graphics.Paint)' on a null object reference
        at com.example.app.MyRoundRectDrawableWithShadow.draw(MyRoundRectDrawableWithShadow.java:172)

Die einfach sagt, dass es eine Schnittstelle abgerufen, die null ist. Dann habe ich mir die CardView Quelle, um herauszufinden, wie Sie es Tat. Ich fand, dass das folgende Stück code initialisiert die Schnittstelle in einige statische Weise (die ich nicht wirklich verstehe warum, erklären Sie bitte, wenn Sie wissen), die ich dann aufrufen, sobald die von der Klasse init, und Sie können dann die Karte der Farbe, die mit dem obigen Stück code.

final RectF sCornerRect = new RectF();
MyRoundRectDrawableWithShadow.sRoundRectHelper
                = new MyRoundRectDrawableWithShadow.RoundRectHelper() {
            @Override
            public void drawRoundRect(Canvas canvas, RectF bounds, float cornerRadius,
                                      Paint paint) {
                final float twoRadius = cornerRadius * 2;
                final float innerWidth = bounds.width() - twoRadius;
                final float innerHeight = bounds.height() - twoRadius;
                sCornerRect.set(bounds.left, bounds.top,
                        bounds.left + cornerRadius * 2, bounds.top + cornerRadius * 2);
                canvas.drawArc(sCornerRect, 180, 90, true, paint);
                sCornerRect.offset(innerWidth, 0);
                canvas.drawArc(sCornerRect, 270, 90, true, paint);
                sCornerRect.offset(0, innerHeight);
                canvas.drawArc(sCornerRect, 0, 90, true, paint);
                sCornerRect.offset(-innerWidth, 0);
                canvas.drawArc(sCornerRect, 90, 90, true, paint);
                //draw top and bottom pieces
                canvas.drawRect(bounds.left + cornerRadius, bounds.top,
                        bounds.right - cornerRadius, bounds.top + cornerRadius,
                        paint);
                canvas.drawRect(bounds.left + cornerRadius,
                        bounds.bottom - cornerRadius, bounds.right - cornerRadius,
                        bounds.bottom, paint);
                //center
                canvas.drawRect(bounds.left, bounds.top + cornerRadius,
                        bounds.right, bounds.bottom - cornerRadius, paint);
            }
        };

Diese Lösung hat jedoch erzeugen ein neues problem. Nicht sicher, was passiert, auf pre-lollipop, aber wenn die CardView ist zunächst initialisiert es scheint, zum erstellen einer RoundRectDrawable wie der hintergrund von den Attributen, die Sie sich gesetzt haben, im XML-Format. Wenn wir ändern Sie dann die Farbe mit dem obigen code legen wir eine MyRoundRectDrawableWithShadow als hintergrund, und wenn man dann die Farbe ändern möchten noch einmal die Karte.getRadius(), Karte.getCardElevation() usw. funktionieren nicht mehr.

Diese daher zuerst versucht werden, um eine Analyse der hintergrund-es wird von der CardView als MyRoundRectDrawableWithShadow, aus dem es kommt dann die Werte, wenn es gelingt (es ist die zweite+ mal, wenn Sie die Farbe ändern). Aber, wenn es scheitert (was das ist, wird auf die erste Farbe ändern, weil der hintergrund eine andere Klasse) es werden die Werte direkt aus der CardView selbst.

    float cardRadius;
    float maxCardElevation;

    try{
        MyRoundRectDrawableWithShadow background = (MyRoundRectDrawableWithShadow)card.getBackground();
        cardRadius = background.getCornerRadius();
        maxCardElevation = background.getMaxShadowSize();
    }catch (ClassCastException classCastExeption){
        cardRadius = card.getRadius();
        maxCardElevation = card.getMaxCardElevation();
    }

    card.setBackgroundDrawable(
            new MyRoundRectDrawableWithShadow(context.getResources(),
                    Color.parseColor(note.getColor()),
                    cardRadius,
                    card.getCardElevation(),
                    maxCardElevation));

Hoffnung, dass Sinn gemacht, ich bin kein native English speaker... Wie erwähnt, wurde nur getestet auf Lollipop.

  • Nicht Bearbeiten Sie Ihre Frage mit Ihrer Lösung. Fügen Sie eine neue Antwort mit es.
InformationsquelleAutor Jakob | 2014-11-07
Schreibe einen Kommentar