Есть ли причина, по которой Google решил не использовать способ динамического изменения цвета фона в CardView?Как изменить цвет фона CardView программно
отрезала here
РЕШЕНИЕ
Простая строка кода @Justin Пауэлл предложил не работает для меня. На Android 5.0 есть. Но это привело меня в правильном направлении.
Этот код (MyRoundRectDrawableWithShadow быть копией this)
card.setBackgroundDrawable(new MyRoundRectDrawableWithShadow(context.getResources(),
color,
card.getRadius(),
card.getCardElevation(),
card.getMaxCardElevation()));
... дал мне эту ошибку,
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)
Который просто говорит, что есть интерфейс вызывался, который является нулевым , Затем я проверил CardView source, чтобы узнать, как он это сделал. Я обнаружил, что следующий фрагмент кода инициализирует интерфейс некоторым статическим способом (я действительно не понимаю, почему, пожалуйста, объясните, если вы знаете), который я затем вызываю один раз в классе init, и вы можете затем установить карту цвета с вышеуказанным куском кода.
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);
}
};
Это решение, однако, порождает новую проблему. Не уверен, что происходит с pre-lollipop, но когда CardView сначала инициализируется, он создает RoundRectDrawable в качестве фона из атрибутов, установленных в XML. Когда мы затем меняем цвет с указанным выше кодом, мы устанавливаем MyRoundRectDrawableWithShadow в качестве фона, и если вы хотите снова изменить цвет еще раз, card.getRadius(), card.getCardElevation() и т. Д. Больше не будет работать.
Это поэтому сначала пытается проанализировать фон, который он получает от CardView, как MyRoundRectDrawableWithShadow, из которого он получает значения, если он преуспеет (что будет вторым + временем, когда вы измените цвет). Но если он не сработает (это будет при первом изменении цвета, потому что фон - это другой класс), он получит значения непосредственно из самого CardView.
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));
Надежда, что имеет смысл, я не носитель английского языка ... Как уже упоминалось, это был протестирован только на леденец.
Не редактируйте свой вопрос с помощью своего решения. Добавьте к нему новый ответ. –