Jetpack-Compose-自定义绘制

本文详细介绍了如何在 Jetpack Compose 中进行自定义绘制,从坐标系的摆正、绘制组件、绘制线条、文字到曲线的美化,通过实例展示了Compose自定义绘制的强大功能,帮助开发者实现更多创意设计。
摘要由CSDN通过智能技术生成
  • 上节课我们简单的利用了一下自定义裁剪自定义就能玩出如下简单案例,效果不错。这节课咋们来看看Compose自定义绘制能不能花里胡哨。

一、Compose自定义

  • 自定义,一个应用的可创造性往往离不开人们的千奇百怪想象和用户变化万千的需求。自定义就是提供了移动端的可创造性。如果Compose没有了自定义那就没有了创造性。自定义不熟悉的看我之前的博客。

    1.Android自定义-曲线渐变填充

    2.Android自定义-手势缩放折线图

    3.Android自定义-手势滑动缩放渐变填充曲线折线图表

    4.艺术在于绘制

    5.绘制相关API…

    









在这里插入图片描述



二、绘制开始

  • 在原生中写过的内容,曲线和的渐变填充其实很简单了,简单的数学加减乘除计算加个塞贝尔曲线而已。接下来咋们看看Compose中如何搞定它。

1.Compose中绘制组件

  • ComposeCanvas作为绘制组件。基本的结构如下,上节课也讲过:
 Canvas(
        modifier = Modifier
            .fillMaxWidth()
            .fillMaxHeight(),
    ) {
    drawIntoCanvas { canvas ->
       //内部提供size来获取自身宽高
    }

2.摆正坐标系

  • 默认的坐标系Android,Flutter,SwiftUI都在左上角咋们试一试Compose坐标系。我们在(100,100)处绘制一个半径为100的红色圆圈,如果出现在屏幕的左上方和下面一致就说明一致。

 Canvas(
        modifier = Modifier
            .fillMaxWidth()
            .fillMaxHeight(),
    ) {
   

        drawIntoCanvas {
    canvas ->
          //
          val paint=Paint()
          paint.style=PaintingStyle.Fill
          paint.color=Color.Green
          canvas.drawCircle(Offset(100f,100f),100f,paint)

        }

    }

效果如下ok坐标系一致,我们绘制开始。

  • 首先摆正坐标系位置目前位置是前面的变为后面的。
    canvas.scale(1f,-1f)+canvas.translate(0f,-height)或者canvas.translate(0f,-height)+canvas.scale(1f,-1f)搞定。不懂的看我自定义的博客


下面代码如果正确那么圆圈应该在左下角

Canvas(
        modifier = Modifier
            .fillMaxWidth()
            .fillMaxHeight(),
    ) {
   

        drawIntoCanvas {
    canvas ->
            //
            val paint = Paint()
            paint.style = PaintingStyle.Fill
            paint.color = Color.Green
            //变坐标轴
            canvas.translate(1f, -1f)
            canvas.drawCircle(Offset(100f, 100f), 100f, paint)

        }

    }

看完效果是不是略显尴尬,刚看到其实我是怀疑模拟器有问题…我们来看真机器华为mate30 pro。完全正确有没有。所以坑挺多的,一不小心就怀疑人生了。

3、绘制平行X轴的横线

  • 首先看原图左右两边都有空格,且坐标系为了方便可以底部和左边留有余地。
@Preview(name = "canvas")
@Composable
fun MyCureView(mainActions: MainActions) {
   
    //距离左边屏幕距离
    val marginToLeft = 180f
    //距离屏幕下边距离
    val marginToBootom = 240f
    

    Canvas(
        modifier = Modifier
            .fillMaxWidth()
            .fillMaxHeight(),
    ) {
   

        drawIntoCanvas {
    canvas ->
            val paint = Paint()
            paint.style = PaintingStyle.Fill
            paint.color = Color.Green
            canvas.translate(0f,size.height)
            canvas.scale(1f, -1f)

            canvas.translate(marginToLeft,marginToBootom)
            canvas.drawCircle(Offset(100f, 100f), 100f, paint)

        }

    }

}

后面如果不够再做调整。我们来绘制一条横线。

 //2.平行x轴线
            val line_paint = Paint()
            line_paint.strokeWidth = 2f
            line_paint.style = PaintingStyle.Stroke
            line_paint.color = Color( 188, 188, 188,100)
            //x轴距离右边也留80距离
            x_scaleWidth = (size.width - marginToLeft - 80f)
            val onePath=Path()
            onePath.lineTo(x_scaleWidth,0f)
            canvas.drawPath(onePath,line_paint)

我们看到总共四条线循环遍历了。

private fun DrawScope.drawXLine(
    x_scaleWidth: Float,
    marginToLeft: Float,
    grid_width: Float,
    canvas: androidx.compose.ui.graphics.Canvas
) {
   
    var x_scaleWidth1 = x_scaleWidth
    var grid_width1 = grid_width
    val line_paint = Paint()
    line_paint.strokeWidth = 2f
    line_paint.style = PaintingStyle.Stroke
    line_paint.color = Color(188, 188, 188, 100)
    //x轴距离右边也留80距离
    x_scaleWidth1 = (size.width - marginToLeft - 80f)
    grid_width1 = x_scaleWidth1 / 6

    val onePath = Path()
    onePath.lineTo(x_scaleWidth1, 0f)
    canvas.drawPath(onePath, line_paint)

    canvas.save()
    //通过平移画布绘制剩余的平行x轴线
    (0 until 3).forEach {
    index ->
        canvas.translate(0f, grid_width1 - 40f)
        canvas.drawPath(onePath, line_paint)
    }
    canvas.restore()
}

当然了手机看着很清晰,图片模糊体谅一下太大了不好处理。

4、绘制文字

  • 绘制文字让我费尽了脑汁。首先是在import androidx.compose.ui.graphics.*一类库下面找了好久好久。由于太天真放弃了一个类一个类的寻找。40多个类让我一个个看么,最后放弃这个法子,然后一顿操作在Google官网各种姿势各种无语呀。上一篇博客半夜有哥们回我万事有google搜索引擎,给我截图发在了评论区,好家伙今早一顿Google搜索有切只有一个Google专家写过一个案例。前无古人后无来者那种。就那一篇,我开心的像个孩子,拿起一顿CV,我特么的傻了,我编译器提示不能解析到nativeCanvas,接下来静下来分析了一波的却在import androidx.compose.ui.graphics.*找到了所在地如下截图。nativaCanvas就是graphics转为原生Canvas。但是我的项目为嘛引用不了呢?而且Google专家没有提供相关的项目。最后我询问了几个大佬未果,最终我怀疑到gradle版本头上,是不是这个常出问题的东西搞的。相信很多写Flutter又没接触过Android的伙伴们深受其害,苦不堪言。将Gradle版本跟新到最新版本即可解决。

Gradle没问题版本gradle-7.0-milestone-2-bin.zip

⭐️⭐️⭐️⭐️⭐️⭐️⭐️⭐️⭐️⭐️⭐️⭐️⭐️⭐️

之前用的6.8版本出问题。
最新
distributionUrl=https\://services.gradle.org/distributions/gradle-7.0-milestone-2-bin.zip

⭐️⭐️⭐️⭐️⭐️⭐️⭐️⭐️⭐️⭐️⭐️⭐️⭐️⭐️

  • canvas.nativeCanvas来进行原生Canvas获取

接着绘制文字即可

1.文字绘制通过paint.getTextBundl不知道的看我之前的自定义文章。
2.x轴的长度和个数知道那么一个的宽度也就能知道x_scaleWidth / 6
3.

fun DrawScope.drawTextDownX(
    x_scaleWidth: Float,
    marginToLeft: Float,
    grid_width: Float,
    canvas: androidx.compose.ui.graphics.Canvas,
    paint: Paint
) {
   
    var x_scaleWidth1 = x_scaleWidth
    var grid_width1 = grid_width
    x_scaleWidth1 = (size.width - marginToLeft - 80f)
    grid_width1 = x_scaleWidth1 / 6
    val text_paint = android.graphics.Paint()
    text_paint.strokeWidth = 2f
    text_paint.style = android.graphics.Paint.Style.STROKE
    text_paint.color = android.graphics.Color.argb(100, 111, 111, 111)
    text_paint.textSize = 19f

    val rectText = Rect()
    canvas.save()
    //将文字旋转摆正,此时坐标系y向下是正
    canvas.scale(1f, -1f)
    (0 until 7).forEach {
    index ->
        if (index > 
评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值