android compose DrawScope - Canvas 使用

android compose DrawScope - Canvas 使用

在 Compose 中绘制自定义内容的核心方法是使用修饰符,例如 Modifier.drawWithContentModifier.drawBehindModifier.drawWithCache

如果您只需使用可组合项进行绘制,可使用 Canvas 可组合项。Canvas 可组合项是一个包裹 Modifier.drawBehind 的便利封装容器。在布局中放置 Canvas 的方式与放置其他 Compose UI 元素相同。在 Canvas 中,您可以通过精确控制元素的样式和位置来绘制元素。

所有绘制修饰符都会提供 DrawScope(一个维护自身状态且限定了作用域的绘制环境),可供您为一组图形元素设置参数。DrawScope 提供了几个有用的字段,例如 size(用于指定 DrawScope 的当前尺寸的 Size 对象)。

复制代码
package com.wn.androidcomposedemo1.basegoogleimage

import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.Canvas
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.width
import androidx.compose.material3.Button
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.graphics.Canvas
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.ImageBitmap
import androidx.compose.ui.graphics.drawscope.DrawScope
import androidx.compose.ui.graphics.drawscope.rotate
import androidx.compose.ui.graphics.drawscope.scale
import androidx.compose.ui.graphics.drawscope.translate
import androidx.compose.ui.res.imageResource
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 16:21
 * Description :
 * 在 Compose 中绘制自定义内容的核心方法是使用修饰符,例如 Modifier.drawWithContent、Modifier.drawBehind 和 Modifier.drawWithCache。
 */
class DrawScopeActivity : ComponentActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        setContent {
            AndroidComposeDemo1Theme() {
                Surface(
                    modifier = Modifier.fillMaxSize(),
                    color = MaterialTheme.colorScheme.background
                ) {
                    DrawScopeExample()
                }
            }
        }
    }

    @Composable
    fun DrawScopeExample(){
        Column(horizontalAlignment = Alignment.CenterHorizontally) {
            Spacer(Modifier.height(20.dp))
            Text("使用DrawScope - Canvas绘制", fontSize = 20.sp, color = Color.Red)
            Spacer(Modifier.height(20.dp))
            var showScale by remember { mutableStateOf(false) }
            var showTranslate by remember { mutableStateOf(false) }
            var showRotate by remember { mutableStateOf(false) }
            var showImage by remember { mutableStateOf(false) }
            Row(horizontalArrangement = Arrangement.Center) {
                Button(onClick = {
                    showScale = !showScale;
                }) {
                    Text("缩放")
                }
                Spacer(Modifier.width(20.dp))
                Button(onClick = {
                    showTranslate  = !showTranslate
                }) {
                    Text("平移")
                }
                Spacer(Modifier.width(20.dp))
                Button(onClick = {
                    showRotate  = !showRotate
                }) {
                    Text("旋转")
                }
                Spacer(Modifier.width(20.dp))
                Button(onClick = {
                    showImage  = !showImage
                }) {
                    Text("绘制图片")
                }
            }
            DrawScopeScaleExample(showScale)
            DrawScopeTranslateExample(showTranslate)
            DrawScopeRotateExample(showRotate)
            DrawScopeImageExample(showImage)
        }
    }

    //缩放
    @Composable
    fun DrawScopeScaleExample(showScale : Boolean){
        if(showScale){
            Canvas(modifier = Modifier.fillMaxSize()) {
                scale(scaleX = 3f, scaleY = 5f){
                    drawCircle(Color.Blue, radius = 20.dp.toPx())
                }
            }
        }
    }

    //平移
    @Composable
    fun DrawScopeTranslateExample(showTranslate : Boolean){
        if(showTranslate){
            Canvas(modifier = Modifier.fillMaxSize()) {
                translate(left = 100f, top = -300f) {
                    drawCircle(Color.Red, radius = 100.dp.toPx())
                }
            }
        }
    }

    //旋转
    @Composable
    fun DrawScopeRotateExample(showRotate: Boolean){
        if(showRotate){
            Canvas(modifier = Modifier.fillMaxSize()){
                rotate(degrees = 45f){
                    drawRect(
                        color = Color.Gray,
                        topLeft = Offset(x = size.width/3f, y = size.height / 3f),
                        size = size / 3f
                    )
                }
            }
        }
    }

    //绘制图片
    @Composable
    fun DrawScopeImageExample(showImage : Boolean){
        val dogImage = ImageBitmap.imageResource(id = R.drawable.dog)
        if(showImage){
            Canvas(modifier = Modifier.fillMaxSize().padding(start = 20.dp, top = 20.dp), onDraw = {
                drawImage(dogImage)
            })
        }
    }
}