Compose笔记(七十四)--BlurMaskFilter

这一节主要了解一下Compose中使用BlurMaskFilter,因为Compose UI组件没有直接封装该API,在Compose中使用BlurMaskFilter,主要是通过DrawScope.drawIntoCanvas结合Android原生Canvas和Paint实现.总结如下:

API:

BlurMaskFilter 用于给绘制内容添加模糊效果,支持如下模糊模式:

栗子:

Kotlin 复制代码
import androidx.compose.foundation.Canvas
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.Slider
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableFloatStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.drawscope.drawIntoCanvas
import androidx.compose.ui.graphics.nativeCanvas
import androidx.compose.ui.unit.dp
import android.graphics.BlurMaskFilter
import android.graphics.Paint

@Composable
fun BlurMaskDemo() {
 
    var blurRadius by remember { mutableFloatStateOf(10f) }

    Column(
        modifier = Modifier.fillMaxSize().padding(20.dp),
        horizontalAlignment = Alignment.CenterHorizontally
    ) {
        
        Text(text = "模糊半径:${blurRadius.toInt()}dp")
        Slider(
            value = blurRadius,
            onValueChange = { blurRadius = it },
            valueRange = 0f..50f,
            modifier = Modifier.padding(horizontal = 20.dp)
        )

       
        Canvas(
            modifier = Modifier
                .fillMaxSize()
                .weight(1f)
        ) {
           
            val textPaint = Paint().apply {
                textSize = 50f 
                color = android.graphics.Color.WHITE
                maskFilter = BlurMaskFilter(blurRadius, BlurMaskFilter.Blur.SOLID)
            }

            drawIntoCanvas { canvas ->
                canvas.nativeCanvas.drawText(
                    "Compose Blur",
                    size.width / 2 - 200f, 
                    size.height / 3,      
                    textPaint
                )
               
                textPaint.maskFilter = null 
                textPaint.color = android.graphics.Color.BLUE
                canvas.nativeCanvas.drawText(
                    "Compose Blur",
                    size.width / 2 - 200f,
                    size.height / 3,
                    textPaint
                )
            }

           
            val circlePaint = Paint().apply {
                color = android.graphics.Color.RED
                isAntiAlias = true
                maskFilter = BlurMaskFilter(blurRadius, BlurMaskFilter.Blur.NORMAL)
            }

            drawIntoCanvas { canvas ->
                canvas.nativeCanvas.drawCircle(
                    size.width / 2,
                    size.height * 2 / 3,
                    80f, 
                    circlePaint
                )
            }
        }
    }
}
Kotlin 复制代码
import android.graphics.BlurMaskFilter
import android.graphics.Paint
import androidx.compose.foundation.Canvas
import androidx.compose.foundation.layout.*
import androidx.compose.material3.Slider
import androidx.compose.material3.Text
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.drawscope.drawIntoCanvas
import androidx.compose.ui.graphics.nativeCanvas
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp

@Composable
fun BlurMaskExample02() {
    var blurRadius by remember { mutableFloatStateOf(30f) }

    Column(
        modifier = Modifier
            .fillMaxSize()
            .padding(20.dp),
        horizontalAlignment = Alignment.CenterHorizontally
    ) {
        Text(
            text = "模糊强度: ${blurRadius.toInt()}",
            fontSize = 18.sp
        )

        Slider(
            value = blurRadius,
            onValueChange = { blurRadius = it },
            valueRange = 0f..80f,
            modifier = Modifier.padding(horizontal = 20.dp)
        )

        Spacer(modifier = Modifier.height(30.dp))

       
        Canvas(
            modifier = Modifier
                .fillMaxWidth()
                .height(450.dp)
        ) {
            val cx = size.width / 2
            val cy = size.height / 2

            drawIntoCanvas { canvas ->
                val nativeCanvas = canvas.nativeCanvas

                val outerPaint = Paint().apply {
                    color = android.graphics.Color.parseColor("#9C27B0")
                    style = Paint.Style.STROKE
                    strokeWidth = 40f
                    isAntiAlias = true
                    maskFilter = BlurMaskFilter(blurRadius, BlurMaskFilter.Blur.OUTER)
                }
                nativeCanvas.drawCircle(cx, cy, 180f, outerPaint)

               
                val middlePaint = Paint().apply {
                    color = android.graphics.Color.parseColor("#00BCD4")
                    style = Paint.Style.STROKE
                    strokeWidth = 35f
                    isAntiAlias = true
                    maskFilter = BlurMaskFilter(blurRadius * 0.8f, BlurMaskFilter.Blur.NORMAL)
                }
                nativeCanvas.drawCircle(cx, cy, 130f, middlePaint)

               
                val innerPaint = Paint().apply {
                    color = android.graphics.Color.parseColor("#FFEB3B")
                    style = Paint.Style.FILL
                    isAntiAlias = true
                    maskFilter = BlurMaskFilter(blurRadius * 0.6f, BlurMaskFilter.Blur.SOLID)
                }
                nativeCanvas.drawCircle(cx, cy, 80f, innerPaint)

               
                val centerPaint = Paint().apply {
                    color = android.graphics.Color.WHITE
                    isAntiAlias = true
                    maskFilter = BlurMaskFilter(25f, BlurMaskFilter.Blur.NORMAL)
                }
                nativeCanvas.drawCircle(cx, cy, 20f, centerPaint)
            }
        }
    }
}

注意:

1 限制模糊绘制的范围

2 避开高频刷新场景

3 避免重复创建Paint和BlurMaskFilter

相关推荐
RainCity1 天前
Java Swing 自定义组件库分享(十二)
java·笔记·后端
李斯维2 天前
从历史的角度看 Android 软件架构
android·架构·android jetpack
alexhilton3 天前
Android车载OS中的Remote Compose
android·kotlin·android jetpack
LinXunFeng8 天前
Obsidian - 使用 Share Note 分享笔记并自部署
前端·笔记·github
alexhilton9 天前
使用Android Archive进行打包
android·kotlin·android jetpack
Junerver12 天前
我写了一个 Compose Multiplatform 组件库,你可能会用到
kotlin·android jetpack
闪闪发亮的小星星13 天前
高斯光以及高斯光公式解释
笔记
cqbzcsq13 天前
CellFlow虚拟细胞论文阅读
论文阅读·人工智能·笔记·学习·生物信息
阿米亚波13 天前
【Windows】QEMU 启动 openEuler aarch64/arm64 架构系统 + 离线软件源
linux·windows·经验分享·笔记·架构·arm
自传.13 天前
尚硅谷 Vibe Coding|第三章(1) Claude Code深度使用与进阶技巧 学习笔记
笔记·学习·尚硅谷·vibecoding