返回

Android Compose 中如何绘制仅在左右两侧有阴影的 Box?

Android

Android Compose 中绘制仅在左右两侧有阴影的 Box

在 Android Compose 中,创建带有阴影的元素很容易,但绘制仅在左右两侧有阴影的 Box 却是一个更具挑战性的任务。本篇文章将探讨如何使用自定义画笔和阴影形状来实现这一目标,并提供一个可供复用的代码实现。

自定义阴影画笔

第一步是创建自定义阴影画笔。这可以通过应用模糊掩码滤镜来实现,该滤镜将阴影平滑并创建模糊效果。在下面的代码中,我们创建了两个画笔:leftShadowPaint 用于左侧阴影,rightShadowPaint 用于右侧阴影。

val leftShadowPaint = Paint().apply {
    isAntiAlias = true
    color = shadowColor
    maskFilter = BlurMaskFilter(shadowRadius, BlurMaskFilter.Blur.NORMAL)
}

val rightShadowPaint = Paint().apply {
    isAntiAlias = true
    color = shadowColor
    maskFilter = BlurMaskFilter(shadowRadius, BlurMaskFilter.Blur.NORMAL)
}

定义阴影形状

接下来,我们需要定义阴影的形状。我们将使用一个 RectF 对象来存储阴影矩形。

val shadowRect = RectF()

在 Canvas 上绘制阴影

onDraw 方法中,我们使用自定义阴影画笔和阴影形状在 Canvas 上绘制阴影。为了仅在 Box 的左右两侧创建阴影,我们需要应用平移变换以调整画布并绘制阴影。

override fun onDraw(canvas: Canvas) {
    super.onDraw(canvas)

    // 左侧阴影
    shadowRect.set(bounds.left, bounds.top, bounds.centerX(), bounds.bottom)
    canvas.drawRect(shadowRect, leftShadowPaint)

    // 右侧阴影
    shadowRect.set(bounds.centerX(), bounds.top, bounds.right, bounds.bottom)
    canvas.drawRect(shadowRect, rightShadowPaint)
}

应用自定义阴影

最后,我们可以将自定义阴影应用于我们的 Box。通过使用 drawBehind 修饰符,我们可以将阴影绘制在 Box 内容的后面。

Box(
    modifier = Modifier
        .drawBehind {
            onDraw(canvas)
        }
) {
    // 内容
}

完整代码

下面提供了完整代码实现:

import androidx.compose.foundation.Canvas
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.*
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.*
import androidx.compose.ui.graphics.drawscope.DrawScope
import androidx.compose.ui.graphics.drawscope.withTransform
import androidx.compose.ui.unit.dp

@Composable
fun ShadowBox(
    content: @Composable ColumnScope.() -> Unit
) {
    val shadowColor = Color.Gray
    val shadowRadius = 10.dp.toPx()

    val leftShadowPaint = Paint().apply {
        isAntiAlias = true
        color = shadowColor
        maskFilter = BlurMaskFilter(shadowRadius, BlurMaskFilter.Blur.NORMAL)
    }

    val rightShadowPaint = Paint().apply {
        isAntiAlias = true
        color = shadowColor
        maskFilter = BlurMaskFilter(shadowRadius, BlurMaskFilter.Blur.NORMAL)
    }

    val shadowRect = RectF()

    Box(
        modifier = Modifier
            .drawBehind {
                withTransform({
                    translate(top = shadowRadius)
                }) {
                    shadowRect.set(bounds.left, bounds.top, bounds.centerX(), bounds.bottom)
                    drawRect(shadowRect, leftShadowPaint)
                }

                withTransform({
                    translate(top = shadowRadius)
                }) {
                    shadowRect.set(bounds.centerX(), bounds.top, bounds.right, bounds.bottom)
                    drawRect(shadowRect, rightShadowPaint)
                }
            }
    ) {
        Column(content = content)
    }
}

通过使用此代码,你可以创建仅在 Box 左右两侧有阴影的阴影效果。

常见问题解答

1. 如何调整阴影的大小?

通过修改 shadowRadius 变量,可以调整阴影的大小。

2. 如何更改阴影颜色?

要更改阴影颜色,请修改 shadowColor 变量。

3. 如何在顶部和底部添加阴影?

要添加顶部和底部阴影,需要修改 onDraw 方法中的阴影形状。

4. 如何使阴影呈圆形?

要创建圆形阴影,需要使用 drawRoundRect 代替 drawRect 来绘制阴影矩形。

5. 如何优化阴影绘制性能?

为了优化阴影绘制性能,可以考虑使用硬件加速或禁用抗锯齿。