You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

API 27及以下版本如何修改视图(含MaterialCardView)阴影颜色?

修改MaterialCardView阴影颜色(API <28)的可行方案

一、原生实现方式

由于API 28以下系统不支持View#setOutlineAmbientShadowColor()和View#setOutlineSpotShadowColor()方法,可通过自定义绘制模拟带颜色的阴影,步骤如下:

  1. 关闭MaterialCardView原生阴影
materialCardView.setCardElevation(0f);
materialCardView.setUseCompatPadding(true); // 可选,避免布局偏移
  1. 自定义阴影Drawable
    通过Paint.setShadowLayer()实现带颜色的模糊阴影,同时匹配CardView圆角:
public class ColoredShadowDrawable extends Drawable {
    private final Paint mShadowPaint;
    private RectF mShadowRect;
    private final float mCornerRadius;
    private final int mShadowColor;
    private final float mShadowRadius;
    private final float mShadowOffsetX;
    private final float mShadowOffsetY;

    public ColoredShadowDrawable(int shadowColor, float shadowRadius, float offsetX, float offsetY, float cornerRadius) {
        mShadowColor = shadowColor;
        mShadowRadius = shadowRadius;
        mShadowOffsetX = offsetX;
        mShadowOffsetY = offsetY;
        mCornerRadius = cornerRadius;

        mShadowPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mShadowPaint.setColor(Color.TRANSPARENT);
        mShadowPaint.setShadowLayer(mShadowRadius, mShadowOffsetX, mShadowOffsetY, mShadowColor);
    }

    @Override
    public void draw(@NonNull Canvas canvas) {
        canvas.drawRoundRect(mShadowRect, mCornerRadius, mCornerRadius, mShadowPaint);
    }

    @Override
    protected void onBoundsChange(Rect bounds) {
        super.onBoundsChange(bounds);
        // 留出阴影绘制空间
        mShadowRect = new RectF(
            bounds.left + mShadowRadius,
            bounds.top + mShadowRadius,
            bounds.right - mShadowRadius,
            bounds.bottom - mShadowRadius
        );
    }

    @Override
    public void setAlpha(int alpha) {
        mShadowPaint.setAlpha(alpha);
    }

    @Override
    public void setColorFilter(@Nullable ColorFilter colorFilter) {
        mShadowPaint.setColorFilter(colorFilter);
    }

    @Override
    public int getOpacity() {
        return PixelFormat.TRANSLUCENT;
    }
}
  1. 将自定义Drawable设置给CardView
    可通过setForeground()或ViewOverlay添加阴影:
ColoredShadowDrawable shadowDrawable = new ColoredShadowDrawable(
    Color.parseColor("#FF6200EE"), // 自定义阴影颜色
    12f, // 阴影模糊半径
    0f, // X轴偏移
    4f, // Y轴偏移
    materialCardView.getRadius() // 和CardView圆角保持一致
);
materialCardView.setForeground(shadowDrawable);

二、性能优异的第三方库

如果不想手动实现,以下第三方库经过性能优化,兼容低版本API:

  • CardViewEx
    扩展原生CardView,直接支持通过XML属性设置阴影颜色、半径和偏移,内部采用硬件加速绘制,性能接近原生:

    <com.example.cardviewex.CardViewEx
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:cardCornerRadius="8dp"
        app:shadowColor="@color/custom_shadow"
        app:shadowRadius="12dp"
        app:shadowOffsetY="4dp">
        <!-- 子布局 -->
    </com.example.cardviewex.CardViewEx>
    
  • DynamicShadowLayout
    轻量级阴影布局容器,支持任意子View(包括MaterialCardView),支持自定义阴影颜色、方向、模糊度,兼容API 16+,全程硬件加速,性能优异:

    <com.example.dynamicshadowlayout.DynamicShadowLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:shadow_color="@color/blue_shadow"
        app:shadow_blur="10dp"
        app:shadow_offset="5dp">
    
        <com.google.android.material.card.MaterialCardView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_margin="10dp"
            app:cardCornerRadius="8dp">
            <!-- 子布局 -->
        </com.google.android.material.card.MaterialCardView>
    
    </com.example.dynamicshadowlayout.DynamicShadowLayout>
    

内容的提问来源于stack exchange,提问作者Mateus Bauer

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.09 08:37:39