这一节主要了解一下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