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

如何为Android布局添加100%圆角的彩色平滑阴影(兼容Android 4.3)

Hey there! I totally get the frustration with android:elevation not working on older Android versions, and third-party libraries not giving you the exact smooth, fully rounded, colored shadow you want. Let’s walk through a few solid, library-free approaches that work great on API 18 (Android 4.3) and up:

1. Use a LayerList Drawable (Simplest Static Solution)

This is the go-to method for static layouts. We’ll stack two rounded shapes: a shadow layer at the bottom, and your content layer on top. The key is matching corner radii and using padding to simulate shadow spread.

Create a new drawable file (res/drawable/layout_with_colored_shadow.xml):

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <!-- Shadow layer: adjust color and padding for desired effect -->
    <item>
        <shape android:shape="rectangle">
            <!-- Colored shadow with alpha (e.g., semi-transparent orange) -->
            <solid android:color="#40FF5722" />
            <!-- Match corner radius of your content -->
            <corners android:radius="24dp" />
            <!-- Padding = shadow size (pushes content layer up/away) -->
            <padding
                android:bottom="4dp"
                android:left="4dp"
                android:right="4dp"
                android:top="4dp" />
        </shape>
    </item>

    <!-- Content layer: your actual layout background -->
    <item>
        <shape android:shape="rectangle">
            <solid android:color="#FFFFFF" />
            <!-- Same corner radius as shadow to avoid gaps -->
            <corners android:radius="24dp" />
            <!-- Padding for your content inside the layout -->
            <padding
                android:bottom="16dp"
                android:left="16dp"
                android:right="16dp"
                android:top="16dp" />
        </shape>
    </item>
</layer-list>

Apply it to your layout:

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="@drawable/layout_with_colored_shadow"
    android:orientation="vertical">

    <!-- Add your text, buttons, etc., here -->

</LinearLayout>

2. Dynamic LayerDrawable (For Runtime Changes)

If you need to adjust shadow color, radius, or size programmatically, build the LayerDrawable in code:

// Initialize shadow drawable
GradientDrawable shadowDrawable = new GradientDrawable();
shadowDrawable.setShape(GradientDrawable.RECTANGLE);
shadowDrawable.setColor(Color.parseColor("#402196F3")); // Blue shadow with alpha
shadowDrawable.setCornerRadius(getResources().getDimension(R.dimen.corner_radius_24dp));

// Initialize content drawable
GradientDrawable contentDrawable = new GradientDrawable();
contentDrawable.setShape(GradientDrawable.RECTANGLE);
contentDrawable.setColor(Color.WHITE);
contentDrawable.setCornerRadius(getResources().getDimension(R.dimen.corner_radius_24dp));
contentDrawable.setPadding(
    (int) getResources().getDimension(R.dimen.padding_16dp),
    (int) getResources().getDimension(R.dimen.padding_16dp),
    (int) getResources().getDimension(R.dimen.padding_16dp),
    (int) getResources().getDimension(R.dimen.padding_16dp)
);

// Combine into LayerList and set insets
LayerDrawable layerDrawable = new LayerDrawable(new Drawable[]{shadowDrawable, contentDrawable});
int shadowInset = (int) getResources().getDimension(R.dimen.shadow_size_4dp);
layerDrawable.setLayerInset(1, shadowInset, shadowInset, shadowInset, shadowInset);

// Apply to your view
yourTargetView.setBackground(layerDrawable);

3. Custom View (For Full Control)

For more advanced scenarios (like dynamic shadow position or gradient shadows), create a custom view that draws the shadow directly on the canvas:

First, define custom attributes in res/values/attrs.xml:

<declare-styleable name="RoundedShadowView">
    <attr name="cornerRadius" format="dimension" />
    <attr name="shadowColor" format="color" />
    <attr name="shadowSize" format="dimension" />
</declare-styleable>

Then create the custom view class:

public class RoundedShadowView extends FrameLayout {
    private Paint shadowPaint;
    private RectF shadowBounds;
    private float cornerRadius;
    private int shadowColor;
    private float shadowSize;

    public RoundedShadowView(Context context) {
        super(context);
        init(null);
    }

    public RoundedShadowView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init(attrs);
    }

    private void init(AttributeSet attrs) {
        setLayerType(LAYER_TYPE_HARDWARE, null); // Enable hardware acceleration for smoothness

        // Load attributes from XML
        TypedArray ta = getContext().obtainStyledAttributes(attrs, R.styleable.RoundedShadowView);
        cornerRadius = ta.getDimension(R.styleable.RoundedShadowView_cornerRadius, 24);
        shadowColor = ta.getColor(R.styleable.RoundedShadowView_shadowColor, Color.parseColor("#40000000"));
        shadowSize = ta.getDimension(R.styleable.RoundedShadowView_shadowSize, 4);
        ta.recycle();

        // Set up shadow paint
        shadowPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        shadowPaint.setColor(shadowColor);
        shadowPaint.setStyle(Paint.Style.FILL);
        shadowPaint.setShadowLayer(shadowSize, 0, shadowSize/2, shadowColor); // Blur, dx, dy, color

        // Add padding to make space for the shadow
        setPadding((int) shadowSize, (int) shadowSize, (int) shadowSize, (int) shadowSize);
        shadowBounds = new RectF();
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        // Adjust shadow bounds to account for padding
        shadowBounds.set(shadowSize, shadowSize, w - shadowSize, h - shadowSize);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        // Draw shadow first, then the content
        canvas.drawRoundRect(shadowBounds, cornerRadius, cornerRadius, shadowPaint);
        super.onDraw(canvas);
    }
}

Use it in your layout:

<com.yourpackage.RoundedShadowView
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    app:cornerRadius="24dp"
    app:shadowColor="#40FF9800"
    app:shadowSize="5dp">

    <!-- Your content layout (match the corner radius!) -->
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="#FFFFFF"
        android:padding="16dp"
        android:orientation="vertical">

        <!-- Your content here -->

    </LinearLayout>

</com.yourpackage.RoundedShadowView>

Quick Tips

  • Always match the corner radius between the shadow and content layers to avoid ugly gaps.
  • Use semi-transparent colors (alpha values like #40 = 64/255) for shadows to keep them smooth and natural.
  • For extra softness, stack multiple shadow layers with varying opacity and sizes in the LayerList.

内容的提问来源于stack exchange,提问作者Abar New

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 09:01:43