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
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.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Ich weiß nicht, von einer bestimmten Argumentation.
Jedoch, wenn Sie interessiert sind, daran herum zu hacken, diese Lücke zu schließen...
Alle CardView mit diesem Attribut erstellen Sie ein abgerundetes Rechteck drawable mit der Farbe, und dann weist Sie, wie der hintergrund der CardView. Wenn Sie wirklich wollen, um die Farbe programmgesteuert, Sie konnte erstellen eine Kopie RoundRectDrawableWithShadow, und dann dies tun:
Können Sie nicht Unterklasse RoundRectDrawableWithShadow oder verwenden Sie es direkt, da es nicht öffentlich ist.
Einfach zu aktualisieren:
Die neueste support-Bibliothek bietet einen direkten Funktion :
setBackgroundColor
aber es war das entfernen meinercornerRadius
und Polster zwischen CardViews. Jetzt funktioniert es wie erwartet.Dies ist schwierig. Sie müssen die hack-API zu acomplish diese Funktion. Die @Justin Powell ' s Antwort ist richtig, aber Abstürze in der API-21. Meine Lösung lösen. Sie müssen dieses add zwei Klassen:
MyRoundRectDrawableWithShadow
:MyRoundRectDrawable
:Und dann diesen code verwenden, um die Hintergrundfarbe zu ändern: