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

如何为圆角半透明矩形Drawable添加边缘渐隐效果?

实现Drawable边缘渐隐的柔和效果

嘿,这个需求很常见,我给你两种实用方案,你可以根据自己的场景选择:

方案1:用XML LayerList快速实现(无需代码)

这种方法适合静态场景,直接通过XML组合多个Drawable层就能搞定,不需要写Java/Kotlin代码。

假设你原来的Drawable是一个带圆角的半透明黑矩形,我们可以在它上面叠加四个边缘的渐变层,让边缘从透明过渡到半透明黑,实现渐隐效果:

<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <!-- 底层:你的原有半透明黑圆角矩形 -->
    <item>
        <shape>
            <solid android:color="#80000000" /> <!-- 半透明黑色,alpha=128 -->
            <corners android:radius="16dp" /> <!-- 圆角大小,和你的原有设置保持一致 -->
        </shape>
    </item>

    <!-- 顶部渐隐层:高度16dp,从透明过渡到半透明黑 -->
    <item>
        <shape>
            <gradient
                android:type="linear"
                android:angle="270" <!-- 从上到下渐变 -->
                android:startColor="#00000000" <!-- 顶部完全透明 -->
                android:endColor="#80000000" /> <!-- 渐变到底部的半透明黑 -->
            <corners
                android:topLeftRadius="16dp"
                android:topRightRadius="16dp" /> <!-- 和底层圆角匹配 -->
        </shape>
        <padding android:top="16dp" /> <!-- 只显示顶部16dp的渐变区域 -->
    </item>

    <!-- 底部渐隐层:高度16dp,从透明过渡到半透明黑 -->
    <item>
        <shape>
            <gradient
                android:type="linear"
                android:angle="90" <!-- 从下到上渐变 -->
                android:startColor="#00000000" <!-- 底部完全透明 -->
                android:endColor="#80000000" /> <!-- 渐变到顶部的半透明黑 -->
            <corners
                android:bottomLeftRadius="16dp"
                android:bottomRightRadius="16dp" />
        </shape>
        <padding android:bottom="16dp" />
    </item>

    <!-- 左侧渐隐层:宽度16dp,从透明过渡到半透明黑 -->
    <item>
        <shape>
            <gradient
                android:type="linear"
                android:angle="0" <!-- 从左到右渐变 -->
                android:startColor="#00000000" <!-- 左侧完全透明 -->
                android:endColor="#80000000" /> <!-- 渐变到右侧的半透明黑 -->
            <corners
                android:topLeftRadius="16dp"
                android:bottomLeftRadius="16dp" />
        </shape>
        <padding android:left="16dp" />
    </item>

    <!-- 右侧渐隐层:宽度16dp,从透明过渡到半透明黑 -->
    <item>
        <shape>
            <gradient
                android:type="linear"
                android:angle="180" <!-- 从右到左渐变 -->
                android:startColor="#00000000" <!-- 右侧完全透明 -->
                android:endColor="#80000000" /> <!-- 渐变到左侧的半透明黑 -->
            <corners
                android:topRightRadius="16dp"
                android:bottomRightRadius="16dp" />
        </shape>
        <padding android:right="16dp" />
    </item>
</layer-list>

你可以调整16dp这个值来控制渐隐的范围,值越大,渐变过渡越平缓。

方案2:自定义Drawable(更灵活可控)

如果需要动态调整渐隐大小、圆角或者颜色,或者要处理更复杂的渐变逻辑,自定义Drawable会更合适。下面是一个Kotlin实现的例子:

import android.graphics.*
import android.graphics.drawable.Drawable
import android.util.TypedValue
import android.content.res.Resources

class FadingEdgeDrawable @JvmOverloads constructor(
    private val cornerRadius: Float = dpToPx(16f),
    private val fadeSize: Float = dpToPx(16f),
    private val bgColor: Int = Color.argb(128, 0, 0, 0)
) : Drawable() {

    private val paint = Paint(Paint.ANTI_ALIAS_FLAG)
    private val rectF = RectF()

    override fun onBoundsChange(bounds: Rect) {
        super.onBoundsChange(bounds)
        rectF.set(bounds)
    }

    override fun draw(canvas: Canvas) {
        // 1. 绘制底层圆角矩形
        paint.color = bgColor
        canvas.drawRoundRect(rectF, cornerRadius, cornerRadius, paint)

        // 2. 绘制顶部渐隐层
        paint.shader = LinearGradient(
            rectF.left, rectF.top,
            rectF.left, rectF.top + fadeSize,
            Color.TRANSPARENT, bgColor,
            Shader.TileMode.CLAMP
        )
        val topRect = RectF(rectF.left, rectF.top, rectF.right, rectF.top + fadeSize)
        canvas.drawRoundRect(topRect, cornerRadius, cornerRadius, paint)

        // 3. 绘制底部渐隐层
        paint.shader = LinearGradient(
            rectF.left, rectF.bottom,
            rectF.left, rectF.bottom - fadeSize,
            Color.TRANSPARENT, bgColor,
            Shader.TileMode.CLAMP
        )
        val bottomRect = RectF(rectF.left, rectF.bottom - fadeSize, rectF.right, rectF.bottom)
        canvas.drawRoundRect(bottomRect, cornerRadius, cornerRadius, paint)

        // 4. 绘制左侧渐隐层
        paint.shader = LinearGradient(
            rectF.left, rectF.top,
            rectF.left + fadeSize, rectF.top,
            Color.TRANSPARENT, bgColor,
            Shader.TileMode.CLAMP
        )
        val leftRect = RectF(rectF.left, rectF.top, rectF.left + fadeSize, rectF.bottom)
        canvas.drawRoundRect(leftRect, cornerRadius, cornerRadius, paint)

        // 5. 绘制右侧渐隐层
        paint.shader = LinearGradient(
            rectF.right, rectF.top,
            rectF.right - fadeSize, rectF.top,
            Color.TRANSPARENT, bgColor,
            Shader.TileMode.CLAMP
        )
        val rightRect = RectF(rectF.right - fadeSize, rectF.top, rectF.right, rectF.bottom)
        canvas.drawRoundRect(rightRect, cornerRadius, cornerRadius, paint)

        // 重置Shader,避免影响后续绘制
        paint.shader = null
    }

    override fun setAlpha(alpha: Int) {
        paint.alpha = alpha
        invalidateSelf()
    }

    override fun setColorFilter(colorFilter: ColorFilter?) {
        paint.colorFilter = colorFilter
        invalidateSelf()
    }

    override fun getOpacity(): Int {
        return PixelFormat.TRANSLUCENT
    }

    private fun dpToPx(dp: Float): Float {
        return TypedValue.applyDimension(
            TypedValue.COMPLEX_UNIT_DIP,
            dp,
            Resources.getSystem().displayMetrics
        )
    }
}

使用的时候直接创建实例并设置给View即可:

val fadingDrawable = FadingEdgeDrawable(
    cornerRadius = dpToPx(16f),
    fadeSize = dpToPx(16f),
    bgColor = Color.argb(128, 0, 0, 0)
)
yourView.background = fadingDrawable

// 辅助方法:dp转px
private fun dpToPx(dp: Float): Float {
    return TypedValue.applyDimension(
        TypedValue.COMPLEX_UNIT_DIP,
        dp,
        resources.displayMetrics
    )
}

总结

  • 如果是静态UI,XML方案足够简单高效,不需要写代码;
  • 如果需要动态调整参数或者更复杂的效果,自定义Drawable能提供更强的灵活性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 07:45:46