android compose drawWithContent 使用
所有绘制命令均在 Compose 中使用绘制修饰符完成。Compose 中有三个主要的绘制修饰符:
基本绘制修饰符为 drawWithContent,您可以在其中确定可组合项的绘制顺序以及从修饰符内发出的绘制命令。drawBehind 是围绕 drawWithContent 的便利封装容器,其绘制顺序设为可组合项内容的后方。drawWithCache 会在其内部调用 onDrawBehind 或 onDrawWithContent,并提供一种机制来缓存在其中创建的对象。

package com.wn.androidcomposedemo1.basegoogleimage
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.aspectRatio
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.drawBehind
import androidx.compose.ui.draw.drawWithCache
import androidx.compose.ui.geometry.CornerRadius
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.geometry.Rect
import androidx.compose.ui.graphics.BlendMode
import androidx.compose.ui.graphics.Brush
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.CompositingStrategy
import androidx.compose.ui.graphics.Path
import androidx.compose.ui.graphics.drawscope.clipPath
import androidx.compose.ui.graphics.graphicsLayer
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.wn.androidcomposedemo1.R
import com.wn.androidcomposedemo1.ui.theme.AndroidComposeDemo1Theme
/**
* Author : wn
* Email : maoning20080808@163.com
* Date : 2026/7/3 17:29
* Description :
* 所有绘制命令均在 Compose 中使用绘制修饰符完成。Compose 中有三个主要的绘制修饰符:
* drawWithContent
* drawBehind
* drawWithCache
*/
class DrawContentActivity : ComponentActivity(){
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
AndroidComposeDemo1Theme() {
Surface(
modifier = Modifier.fillMaxSize(),
color = MaterialTheme.colorScheme.background
) {
DrawBehindDemo()
}
}
}
}
@Composable
fun DrawBehindDemo(){
Column(horizontalAlignment = Alignment.CenterHorizontally) {
Spacer(Modifier.height(20.dp))
Text("使用Modifier.drawBehind、drawWithCache", fontSize = 20.sp, color = Color.Red)
Spacer(Modifier.height(20.dp))
DrawBehindExample()
Spacer(Modifier.height(20.dp))
DrawWithCacheExample()
Spacer(Modifier.height(20.dp))
BlendModeExample()
Spacer(Modifier.height(20.dp))
BlendModeExample2()
}
}
@Composable
fun DrawBehindExample(){
Text("Hello Compose!", fontSize = 30.sp,
modifier = Modifier.drawBehind{
drawRoundRect(Color(0xFFBBAAEE),
cornerRadius = CornerRadius(10.dp.toPx())
)
}.padding(12.dp)
)
}
@Composable
fun DrawWithCacheExample(){
Text("Hello Compose!", fontSize = 30.sp,
modifier = Modifier
.drawWithCache{
val brush = Brush.linearGradient(
listOf(
Color(0xFF9E82F0),
Color(0xFF42A5F5)
)
)
onDrawBehind {
drawRoundRect(
brush,
cornerRadius = CornerRadius(10.dp.toPx())
)
}
}
.padding(12.dp)
)
}
@Composable
fun BlendModeExample(){
Image(
painter = painterResource(id = R.drawable.dog),
contentDescription = stringResource(R.string.image_description),
contentScale = ContentScale.Crop,
modifier = Modifier
.size(200.dp)
.aspectRatio(1f)
.background(
Brush.linearGradient(
listOf(
Color(0xFFC5E1A5),
Color(0xFF80DEEA)
)
)
)
.padding(18.dp)
.graphicsLayer{
compositingStrategy = CompositingStrategy.Offscreen
}
.drawWithCache{
val path = Path()
path.addOval(
Rect(
topLeft = Offset.Zero,
bottomRight = Offset(size.width, size.height)
)
)
onDrawWithContent {
clipPath(path){
this@onDrawWithContent.drawContent()
}
val dotSize = size.width / 8f
drawCircle(
Color.Black,
radius = dotSize,
center = Offset(
x = size.width - dotSize,
y = size.height - dotSize
),
blendMode = BlendMode.Clear
)
drawCircle(
Color(0xFFEF5350), radius = dotSize * 0.8f,
center = Offset(
x = size.width - dotSize,
y = size.height - dotSize
)
)
}
}
)
}
//不使用CompositingStrategy.Offscreen
@Composable
fun BlendModeExample2(){
Image(
painter = painterResource(id = R.drawable.dog),
contentDescription = stringResource(R.string.image_description),
contentScale = ContentScale.Crop,
modifier = Modifier
.size(200.dp)
.aspectRatio(1f)
.background(
Brush.linearGradient(
listOf(
Color(0xFFC5E1A5),
Color(0xFF80DEEA)
)
)
)
.padding(18.dp)
.graphicsLayer{
//compositingStrategy = CompositingStrategy.Offscreen
}
.drawWithCache{
val path = Path()
path.addOval(
Rect(
topLeft = Offset.Zero,
bottomRight = Offset(size.width, size.height)
)
)
onDrawWithContent {
clipPath(path){
this@onDrawWithContent.drawContent()
}
val dotSize = size.width / 8f
drawCircle(
Color.Black,
radius = dotSize,
center = Offset(
x = size.width - dotSize,
y = size.height - dotSize
),
blendMode = BlendMode.Clear
)
drawCircle(
Color(0xFFEF5350), radius = dotSize * 0.8f,
center = Offset(
x = size.width - dotSize,
y = size.height - dotSize
)
)
}
}
)
}
}