此问题在此处已有答案:
Change the background color of CardView programmatically(27个答案)
9小时前关门了。
Google决定不开发动态改变CardView背景颜色的方法,这是有原因的吗?
剪断here x1c 0d1x
变通办法
@Justin Powell建议的简单代码行对我不起作用。在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)
这只是说有一个接口被调用为null。然后我检查了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);
}
};
但是这个解决方案产生了一个新的问题。不知道在棒棒糖之前会发生什么,但是当CardView第一次初始化时,它似乎从您在XML中设置的属性创建了一个RoundRectDrawable作为背景。当我们用上面的代码更改颜色时,我们设置了一个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));
希望这是有意义的,我不是一个母语为英语的人...如前所述,这只是在棒棒糖测试。
4条答案
按热度按时间b1uwtaje1#
仅更新:最新的支持库提供了一个直接函数:
dbf7pr2w2#
"我不知道有什么特别的理由"
不过,如果你有兴趣破解这个漏洞......
CardView使用这个属性所做的一切就是创建一个圆角矩形,然后将其指定为CardView的背景。如果你真的想以编程方式设置颜色,你可以创建一个RoundRectDrawableWithShadow的副本,然后执行以下操作:
不能将 RoundRectDrawableWithShadow 作为子类或直接使用,因为它不是公共的。
dddzy1tm3#
这很棘手。你需要破解API来完成这个功能。@Justin Powell的答案是正确的,但是在API 21中崩溃了。我的解决方案解决了这个问题。你需要添加这两个类:
MyRoundRectDrawableWithShadow
:MyRoundRectDrawable
:然后使用以下代码更改背景颜色:
k0pti3hp4#
只需编写以下代码片段:
cardView.setCardBackgroundColor(getResources().getColor(R.color.colorPrimary));
您想要代码的位置