如何以编程方式更改CardView的背景颜色

Jak*_*kob 0 android android-cardview android-5.0-lollipop

Google有没有理由决定不采用动态更改CardView背景颜色的方法?

在这里剪了一下 在此输入图像描述


替代方法

@Justin Powell建议的简单代码对我不起作用.在Android 5.0上.但它确实让我朝着正确的方向前进.

此代码,(MyRoundRectDrawableWithShadow是副本这个)

        card.setBackgroundDrawable(new MyRoundRectDrawableWithShadow(context.getResources(),
                color,
                card.getRadius(),
                card.getCardElevation(),
                card.getMaxCardElevation()));
Run Code Online (Sandbox Code Playgroud)

......给了我这个错误,

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)
Run Code Online (Sandbox Code Playgroud)

这简单地说有一个被调用的接口是null.然后我查看了CardView源代码,了解它是如何做到的.我发现下面的一段代码以某种静态的方式初始化接口(我真的不明白为什么,如果你知道的话请解释),然后我在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);
            }
        };
Run Code Online (Sandbox Code Playgroud)

然而,该解决方案确实产生了新问题.不确定在棒棒糖前发生了什么,但是当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));
Run Code Online (Sandbox Code Playgroud)

希望这是有道理的,我不是母语为英语的人......如上所述,这只是在Lollipop上测试过的.

vj9*_*vj9 18

只是为了更新:最新的支持库提供了直接的功能:

CardView cardView;
cardView.setCardBackgroundColor(color);
Run Code Online (Sandbox Code Playgroud)