Jetpack-Compose-自定义绘制

2023-05-16

  • 上节课我们简单的利用了一下自定义裁剪自定义就能玩出如下简单案例,效果不错。这节课咋们来看看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 > 0) {
            Log.e("weima?", "MyCureView: " + grid_width1)
            canvas.nativeCanvas.translate(grid_width1, 0f)
        }
        val strTx = "11.${11 + index}"
        text_paint.getTextBounds(strTx, 0, strTx.length, rectText)
        canvas.nativeCanvas.drawText(
            strTx,
            -rectText.width().toFloat() / 2,
            rectText.height().toFloat() * 2.5f,
            text_paint
        )
    }
    canvas.restore()
}


同样的绘制Y轴左边的文字。

private fun DrawScope.drawTextOfYLeft(
    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 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

    x_scaleWidth1 = (size.width - marginToLeft - 80f)
    grid_width1 = x_scaleWidth1 / 6

    val rectText = Rect()
    canvas.save()
    //将文字旋转摆正,此时坐标系y向下是正
    (0 until 4).forEach { index ->
        if (index > 0) {
            canvas.translate(0f, grid_width1 - 40f)
        }
        var strTx = ""
        if (index == 0) {
            strTx = "${index}"
        } else if (index == 1) {
            strTx = "${500}"
        } else if (index == 2) {
            strTx = "1k"
        } else {
            strTx = "1.5k"
        }

        canvas.save()
        canvas.scale(1f, -1f)
        text_paint.getTextBounds(strTx, 0, strTx.length, rectText)
        canvas.nativeCanvas.drawText(
            strTx,
            -rectText.width().toFloat() - 42f,
            rectText.height().toFloat() / 2,
            text_paint
        )
        canvas.restore()
    }
    canvas.restore()
}

5、绘制曲线

y 1 y_1 y1< y 2 y_2 y2如上图1.求出中点坐标x轴下部分控制点x+40px,上部分x-40px,y轴也可以调整来搞搞平滑度下部分控制点y-40x,上部分y+40。
1.获取中点的坐标( X 中 X_中 X Y 中 Y_中 Y)= (( x 1 x_1 x1+ x 2 x_2 x2)/2、( y 1 y_1 y1+ y 2 y_2 y2)/2)
2. x 1 x_1 x1 X 中 X_中 X之间的坐标=(( x 1 x_1 x1+ x 中 x_中 x)/2、( y 1 y_1 y1+ y 中 y_中 y)/2)
3. x 中 x_中 x X 2 X_2 X2之间的坐标=(( x 中 x_中 x+ x 2 x_2 x2)/2、( y 中 y_中 y+ y 2 y_2 y2)/2)

y 1 y_1 y1> y 2 y_2 y2如上图2.求出中点坐标x轴上部分+40px,下部分x-40px,y轴也可以调整,y轴也可以调整来搞搞平滑度上部分控制点y+40x,下部分y-40。
1.获取中点的坐标( X 中 X_中 X Y 中 Y_中 Y)= (( x 1 x_1 x1+ x 2 x_2 x2)/2、( y 1 y_1 y1+ y 2 y_2 y2)/2)
2. x 1 x_1 x1 X 中 X_中 X之间的坐标=(( x 1 x_1 x1+ x 中 x_中 x)/2、( y 1 y_1 y1+ y 中 y_中 y)/2)
3. x 中 x_中 x X 2 X_2 X2之间的坐标=(( x 中 x_中 x+ x 2 x_2 x2)/2、( y 中 y_中 y+ y 2 y_2 y2)/2)

private fun DrawScope.drawCubtoCircle(
    x_scaleWidth: Float,
    marginToLeft: Float,
    grid_width: Float,
    dataList: ArrayList<Int>,
    canvas: androidx.compose.ui.graphics.Canvas
) {
    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.FILL
    text_paint.color = android.graphics.Color.argb(100, 111, 111, 111)

    val caves_path = android.graphics.Path()
    //500=grid_width-40 每个单位的长度的=像素长度
    val danweiY = (grid_width1 - 40) / 500
    val danweiX = (grid_width1)
    val linearGradient = LinearGradient(
        0f, 1500 * danweiY,
        0f,
        0f,
        android.graphics.Color.argb(255, 229, 160, 144),
        android.graphics.Color.argb(255, 251, 244, 240),
        Shader.TileMode.CLAMP
    )
    text_paint.shader = linearGradient
    for (index in 0 until dataList.size - 1) {
        val xMoveDistance = 20
        val yMoveDistance = 40

        if (dataList[index] == dataList[index + 1]) {
            caves_path.lineTo(danweiX * (index + 1), 0f)
        } else if (dataList[index] < dataList[index + 1]) {//y1<y2情况
            val centerX = (grid_width1 * index + grid_width1 * (1 + index)) / 2
            val centerY =
                (dataList[index].toFloat() * danweiY + dataList[index + 1].toFloat() * danweiY) / 2
            val controX0 = (grid_width1 * index + centerX) / 2
            val controY0 = (dataList[index].toFloat() * danweiY + centerY) / 2
            val controX1 = (centerX + grid_width1 * (1 + index)) / 2
            val controY1 = (centerY + dataList[index + 1].toFloat() * danweiY) / 2
            caves_path.cubicTo(
                controX0 + xMoveDistance,
                controY0 - yMoveDistance,
                controX1 - xMoveDistance,
                controY1 + yMoveDistance,
                grid_width1 * (1 + index),
                dataList[index + 1].toFloat() * danweiY
            )
        } else {
            val centerX = (grid_width1 * index + grid_width1 * (1 + index)) / 2
            val centerY =
                (dataList[index].toFloat() * danweiY + dataList[index + 1].toFloat() * danweiY) / 2
            val controX0 = (grid_width1 * index + centerX) / 2
            val controY0 = (dataList[index].toFloat() * danweiY + centerY) / 2
            val controX1 = (centerX + grid_width1 * (1 + index)) / 2
            val controY1 = (centerY + dataList[index + 1].toFloat() * danweiY) / 2
            caves_path.cubicTo(
                controX0 + xMoveDistance,
                controY0 + yMoveDistance,
                controX1 - xMoveDistance,
                controY1 - yMoveDistance,
                grid_width1 * (1 + index),
                dataList[index + 1].toFloat() * danweiY
            )

        }
    }
    canvas.nativeCanvas.drawCircle(0f, 0f, 10f, text_paint)
    //绘制闭合渐变曲线
    canvas.nativeCanvas.drawPath(caves_path, text_paint)
    val line_paint = android.graphics.Paint()
    line_paint.strokeWidth = 3f
    line_paint.style = android.graphics.Paint.Style.STROKE
    line_paint.color = android.graphics.Color.argb(255, 212, 100, 77)
    //绘制外环红色线
    canvas.nativeCanvas.drawPath(caves_path, line_paint)
    line_paint.style = android.graphics.Paint.Style.FILL
    //画圈。
    for (index in 0 until dataList.size) {
        canvas.nativeCanvas.drawCircle(
            grid_width1 * index,
            danweiY * dataList[index],
            8f,
            line_paint
        )
    }
}

到这里我们最大的困难也简单的解决了吧?无非简单的加减乘除是不是?接下来我们进行装饰美丽的曲线,学过之前的文章对于这几点技能我想我们都熟能生巧的创作了吧?渐变填充动画点击、`

6、曲线美化

  • ⭐️⭐️⭐️⭐️⭐️在自定义绘制中如果你对Compose的Api使用蹩脚,那完全可以通过 canvas.nativeCanvasCanvas转换为原生这样你可以任意切换在两个canvas之间操作⭐️⭐️⭐️⭐️⭐️⭐️⭐️⭐️
private fun DrawScope.drawResultBitifull(canvas: androidx.compose.ui.graphics.Canvas) {
    val text_paint = android.graphics.Paint()
    text_paint.strokeWidth = 2f
    text_paint.style = android.graphics.Paint.Style.FILL
    text_paint.color = android.graphics.Color.argb(255, 0, 0, 0)
    text_paint.textSize = 66f
    val rectText = Rect()
    val rectTextYuan = Rect()

    canvas.save()
    canvas.scale(1f, -1f)
    canvas.translate((size.width / 2).toFloat() - 100, -500f)
    val text = "1347"
    val textyu = "元"

    text_paint.getTextBounds(text, 0, text.length, rectText)

    canvas.nativeCanvas.drawText(
        text,
        -rectText.width().toFloat() - 42f,
        rectText.height().toFloat() / 2,
        text_paint
    )
    text_paint.color = android.graphics.Color.argb(111, 111, 111, 111)
    text_paint.getTextBounds(textyu, 0, textyu.length, rectTextYuan)
    text_paint.textSize = 33f
    canvas.nativeCanvas.drawText(
        textyu,
        80 + -rectTextYuan.width().toFloat() - 42f,
        rectTextYuan.height().toFloat() / 2,
        text_paint
    )

    canvas.translate(0f, 50f)
    canvas.nativeCanvas.drawText(
        "较前天",
        -rectTextYuan.width().toFloat() - 180f,
        rectTextYuan.height().toFloat() / 2,
        text_paint
    )
    canvas.translate(100f, 0f)
    text_paint.color = android.graphics.Color.argb(255, 223, 129, 120)
    canvas.nativeCanvas.drawText(
        "+971.99(251.19%)",
        -rectTextYuan.width().toFloat() - 180f,
        rectTextYuan.height().toFloat() / 2,
        text_paint
    )
    canvas.translate(-100f, 50f)
    text_paint.color = android.graphics.Color.argb(111, 111, 111, 111)
    canvas.nativeCanvas.drawText(
        "对应图中虚线部分进行最高评奖",
        -rectTextYuan.width().toFloat() - 180f,
        rectTextYuan.height().toFloat() / 2,
        text_paint
    )
    //暂时没找到canvas绘制富文本的方法。只能一个个测量绘制文字了。别学我,好好测量测量有待提高自己的小学计算。

    canvas.restore()
}

//8.绘制每天最高获得者的头像...纯虚构故事对不对..
private fun drawHeaderToCanvas(canvas: Canvas,width:Float,marginToLeft:Float,dataList:List<Int>,imgList:ArrayList<ImageBitmap>) {
    val bitmap_paint = android.graphics.Paint()
    bitmap_paint.strokeWidth = 2f
    bitmap_paint.style = android.graphics.Paint.Style.STROKE
    bitmap_paint.xfermode = PorterDuffXfermode(PorterDuff.Mode.SRC_IN)
    bitmap_paint.isAntiAlias =true
    canvas.save()
    val srcRect1=Rect(0, 0, 80, 80)
    val dstRect1=Rect(0, 0, 40, 40)
    val x_scaleWidth = (width - marginToLeft - 80f)
    val grid_width = x_scaleWidth / 6
    val danweiY = (grid_width - 40) / 500
    for (index in 0 until dataList.size) {
        val bitmap = imgList[index].asAndroidBitmap()
        canvas.save()
        canvas.translate(
            grid_width * index - bitmap.width /20,
            danweiY * dataList[index] + 20
        )
        //这里绘制图片到画布上
        val circlePath = Path()
        circlePath.addCircle(20f,20f, 20f, Path.Direction.CCW)
        canvas.clipPath(circlePath)
        canvas.drawBitmap(bitmap, srcRect1, dstRect1, bitmap_paint)
        canvas.restore()
    }
    canvas.restore()


}

@SuppressLint("ObsoleteSdkInt")
fun drawTextButton(canvas: Canvas) {
    val line_paint = android.graphics.Paint()
    line_paint.strokeWidth = 2f
    line_paint.style = android.graphics.Paint.Style.STROKE
    line_paint.color = android.graphics.Color.argb(188, 76, 126, 245)
    line_paint.textSize=32f
    val buttonPath = android.graphics.Path()
    if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {
        buttonPath.addRoundRect(110f, -120f, 270f, -180f, 80f, 80f, android.graphics.Path.Direction.CCW)
    }
    canvas.drawPath(buttonPath, line_paint)
    canvas.save()
    canvas.scale(1f, -1f)
    line_paint.style = android.graphics.Paint.Style.FILL
    canvas.drawText("前 七 天", 140f, 165f, line_paint)
    canvas.restore()

    canvas.save()
    canvas.translate(260f, 0f)
    line_paint.style = android.graphics.Paint.Style.STROKE
    canvas.drawPath(buttonPath, line_paint)
    canvas.scale(1f, -1f)
    line_paint.style = android.graphics.Paint.Style.FILL
    canvas.drawText("后 七 天", 140f, 165f, line_paint)
    canvas.restore()

}

三、总结

  • 自定义不仅提供了更方便的API,而且可以完全使用原来的API,所以原生Android开发还是很香的,Compose里面自定义完全没想到再次分装的点,但是对于我们来说不就多了一些选择么。所以自定义完全没问题。而且创造性完全不输任何端,只是顶层的API定义有所不同罢了。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Jetpack-Compose-自定义绘制 的相关文章

  • Jetpack Compose 从入门到入门(四)

    本篇开始介绍Jetpack Compose 中常用的组件 有一部分之前的文章中也出现过 xff0c 今天详细说明一下 1 Text 日常最常用的应该就是显示文字 xff0c 所以有必要说一下Text控件 首先源码如下 xff1a span
  • Jetpack Compose 从入门到入门(八)

    接着上一篇的动画部分 xff0c 本篇主要是自定义动画与Animatable AnimationSpec 上一篇中 xff0c 出现了多次animationSpec属性 xff0c 它是用来自定义动画规范的 例如 xff1a span cl
  • Jetpack Compose 从入门到入门(十)

    本篇介绍如何将Jetpack Compose 添加到已有应用中 xff0c 毕竟大多数情况都是在现有项目中使用 Jetpack Compose 旨在配合既有的基于 View 的界面构造方式一起使用 如果您要构建新应用 xff0c 最好的选择
  • 树莓派安装 docker 和 docker-compose

    树莓派安装 docker 和 docker compose 本文地址 xff1a blog lucien ink archives 518 因为总是频繁地初始化树莓派 xff0c 所以把安装 docker 的过程也记录下来 1 安装 doc
  • Docker——(十五)Docker Compose 实战 MySQL

    MySQL5 version 39 3 1 39 services mysql restart always image mysql 5 7 22 container name mysql ports 3306 3306 environme
  • docker-compose构建mysql服务

    docker安装mysql服务显得很快捷 xff0c 我们如果使用了docker compose那就更快了 xff0c 我们只需要按照我们的要求 xff0c 设置相应的端口映射 xff0c 如果有需求 xff0c 也可以设置数据映射 配置如
  • Docker Compose部署Springboot+Mysql项目

    声明 xff1a 本文CSDN作者原创投稿文章 xff0c 未经许可禁止任何形式的转载 xff0c 原文链接 在上一篇文章Spring Boot Maven 43 Docker打包中 xff0c 我们实现了将Springboot项目源代码一
  • JETSON TX2镜像备份与恢复以及刷机的巨详细教程(Jetpack 4.4版本)

    摘自 xff1a https blog csdn net Feizhai2 article details 109068697 utm medium 61 distribute pc relevant t0 none task blog B
  • Docker之基于docker-compose创建vsftpd容器

    前言 因为本人很菜 xff0c 每次配置vsftpd都头疼的要死 又因为网上vsftpd的教程会版本不一导致配置总是会出错 因此尝试使用docker来解决这个问题 而单纯只是用docker每次启动需要输入长串命令 xff0c 因此再结合do
  • Jetpack刷机TX2(大坑)【记录问题】

    Jetpack刷机TX2 xff08 大坑 xff09 1 Jetson TX2 刷机时遇到的坑 xff1a https blog csdn net zshluckydogs article details 79855631 xff01 x
  • 【ROS2 入门】Jeston TX1 JetPack_4.6.3环境 ubuntu 18.04 ROS2 安装

    大家好 xff0c 我是虎哥 xff0c 从今天开始 xff0c 我将花一段时间 xff0c 开始将自己从ROS1切换到ROS2 xff0c 在上一篇中 xff0c 我们再虚拟机环境中安装了 ROS2 eloquent版本 xff0c 并完
  • 【笔记】docker-compose.yml 文件更改后重新启动加载更改后的内容

    docker compose yml 文件更改后想使之立刻生效 xff0c 但是不想手动删除已经建立的 container 等信息可以运行下面命令 重新创建容器实现修改 docker compose up force recreate d
  • Jetson tx2(JetPack 4.4)配置pytorch环境

    下载pytorch 下载pytorch1 7 xff1a 我的系统是JetPack4 4 xff0c 要求pytorch gt 61 1 7 安装pytorch span class token function sudo span spa
  • Android DataBinding的基本使用

    5 DataBinding https developer android com topic libraries data binding custom conversions 数据绑定库是一种支持库 借助该库 您可以使用声明性格式 而非
  • jetpack Compose 学习笔记

    目录 Modifier clickable 取消点击水波纹 LazyColum 相关 Modifier clickable 取消点击水波纹 modifier Modifier clickable onClick indication nul
  • Jetpack学习之Lifecycle

    Jetpack是Google为了解决Android架构问题而引入的 Google官方说的说法 Jetpack是一套库 工具和指南 可以帮助开发者更轻松地编写应用程序 Jetpack中的组件可以帮助开发者遵循最佳做法 摆脱编写样板代码的工作并
  • Jetpack学习之MVVM实战

    MVVM架构与Jetpack MVVM即Model View ViewModel的缩写 它的出现是为了将图形界面与业务逻辑 数据模型进行解耦 MVVM也是Google推崇的一种Android项目架构模型 而Jetpack组件 大部分是为了能
  • Jetpack-Compose之一基础使用

    一 命令式UI和申明式UI 如果之前有了解或者使用果Flutter 应该会对命令式UI这种架构不陌生 目前申明式UI确实是很火包含Flutter SwiftUI JetpackCompose都使用了该种方式 2021年7月底 Google
  • Navigation Preview unavailable in Android Studio 3.4 Preview

    Navigation Preview unavailable in Android Studio 3 4 Preview 最近在学Jetpack Navigation组件 但是在写navigation资源文件的时候 Preview 显示不出
  • 一文带你了解ViewModel

    Lifecycle库可以有效避免内存泄漏和解决常见的Android生命周期难题 1 引言 ViewModel属于lifecycle 生命周期感知型组件 中的一员 通常与LiveData DataBinding一起使用 它们是MVVM架构的重

随机推荐

  • Cause: org.apache.ibatis.executor.ExecutorException: A query was run and no Result Maps were found

    org apache ibatis exceptions PersistenceException Error updating database Cause org apache ibatis executor ExecutorExcep
  • [Linux] 记录一次批量开关机操作

    最近公司需要停一部分机器测试下业务稳定性 关停很简单 ansible 就可以了 xff0c 一句命令 ansible guanji m command a 34 shutdown h now 34 定义的关机组 guanji 过了两周 xf
  • 生活篇

    春天 xff0c 一个诗情画意的季节 xff0c 一个生机勃勃的季节 春天 xff0c 为我们带来了温暖 xff0c 为大地带来了生机 在这个春意盎然的季节 xff0c 大自然也开始了她们的春天交响曲 我喜欢三月 xff0c 我也讨厌三月
  • WebStorm 2023.1 最新变化【附带ChatGPT教程】

    ChatGPT开源公众号 xff1a https gitee com wy521a astar weixin mp 观看更新概览视频 在浏览器中打开更新变化 WebStorm 2023 1 最新变化 框架和技术 Astro 支持 备受期待的
  • Ubuntu18.04解决gnome-tweak-tool安装后shell主题提示user-theme extension没有启用的问题

    换用Ubuntu18之后 xff0c 桌面又回到了gnome xff0c 因此找到了gnome tweak tool对桌面进行美化 1 安装gnome tweak tool sudo apt get install gnome tweak
  • 多生产者和多消费者问题

    题目描述 桌子上有一个盘子 xff0c 每次只能向其中放入一个水果 爸爸专门向盘子里面放苹果 xff0c 妈妈专门向盘子里面放橘子 xff1b 只有盘子为空时 xff0c 爸爸或妈妈才可以向其中放入水果 xff1b 仅当盘子里有自己需要的水
  • ssh远程连接服务器常用命令

    命令行下 xff0c 使用ssh 远程登录服务器 ssh 39 用户名 39 64 39 IP地址 39 不用加 39 号 xff0c 这里是为了作区分 39 用户名 39 64 39 IP地址 39 39 s password xxx 项
  • 记录在安卓webview上,gif,apng,pixi.js,lottie-web动画导致闪屏问题

    随着公司项目对动画要求越来越高 xff0c 从由美术提供简单的gif 或者css js开发简单动画变成了使用渲染引擎pixi js使用序列帧动画 xff0c 或者使用龙骨 xff0c spine等更加复杂炫酷的动画 但是发现屏幕在播放动画的
  • 黑苹果_万能OpenCore_0.8.4_EFI

    对于喜欢折腾黑苹果的人来说 xff0c 安装Mac系统就是家常便饭 xff0c 其中最重要的就是EFI的配置 xff0c 配置出一个适合自己电脑的EFI很重要 xff0c 今天发布这篇文章就是为了提供给新加入的伙伴们 xff0c 让更多的伙
  • 黑苹果_OpenCore_0.8.4各项功能精解

    黑苹果已经延续有些年了 xff0c 引导也更新换代过好几次 xff0c 安装黑苹果的第一个条件就是需要拥有一个支持引导苹果系统的EFI xff0c 否则 xff0c 连苹果皮都看不到 xff0c 虽然网上可以直接下载EFI xff0c 但是
  • Github域名解析连接慢问题

    Github域名解析连接慢问题 1 Github访问慢问题2 Github连接解决方案2 1 使用 Gitee 的镜像仓库2 2 配置本地的 hosts 文件 3 DNS域名解析分析3 1 根域名服务器3 1 顶级域名服务器3 1 域名解析
  • C++判断素数(求素数)

    素数又称质数 所谓素数是指除了 1 和它本身以外 xff0c 不能被任何整数整除的数 xff0c 例如17就是素数 xff0c 因为它不能被 2 16 的任一整数整除 思路1 xff1a 因此判断一个整数m是否是素数 xff0c 只需把 m
  • Directx工具修复工具,专注修复C++动态链接DLL文件

    问题 xff1a 方法一 xff1a 可以直接去360管家中搜索DirectX xff0c 然后下载 xff0c 进行修复 方法二 xff1a 如下 xff1a DirectX修复工具最新版 xff1a DirectX Repair V3
  • shell脚本实现在任意虚拟机上 一键重启/关闭 多台虚拟机

    shell脚本实现在任意虚拟机上 一键重启 关闭 多台虚拟机 span class token operator span span class token operator span bin span class token operat
  • ChatGPT体验地址,超多功能,附公众号源码

    GPT 说明效果演示地址体验公众号源码 说明 ChatGPT是一种基于深度学习的自然语言处理 xff08 NLP xff09 技术 xff0c 它可以实现自然的文字对话 ChatGPT是基于预训练的语言模型 xff0c 使用大量的数据和计算
  • Android Native内存泄漏案例

    文章目录 背景现状malloc debugLeakTracer综合评估功能性能稳定性治理实践 案例 使用Raphael 定位内存泄漏 项目中遇到一个内存泄漏的情形 xff1a usb camera预览时出现了内存泄漏 xff0c 但内存泄漏
  • 【The 2017 BAPC】C题-Collatz Conjecture ---- GCD+优化去重

    题意 给你一个大小为n的序列 xff0c 让你求里面所有子串的GCD xff0c 求里面最多有多少不同的GCD 思路 xff1a 利用集合set tmp维护 到当前子串的最后一个元素的所有GCD xff0c set ans保存所有不同种类的
  • WGS84与大地2000坐标转换(Java,C#,Dart)

    一 坐标转换的必要性 平面坐标在道路测绘 隧道测量 农业建筑业等室外勘测等方面有着广泛的应用 各行业基本都会涉及到移动端测量之后不能满足屏幕坐标 所以需要经纬度的转换 移动端勘测结果都是WGS84坐标或者GCJ 02格式坐标 而实际工程项目
  • Flutter百度地图

    Flutter百度地图 重构项目 一 实现效果如下图 qq交流群 群号 730772561 1 地图中任意踩点进行杆塔和设备的新建 对与点和线进行关联 2 对于点和线进行各种操作 3 自定义区域下载离线地图 4 热烈线 5 自定义瓦片地图
  • Jetpack-Compose-自定义绘制

    上节课我们简单的利用了一下自定义裁剪和自定义就能玩出如下简单案例 效果不错 这节课咋们来看看Compose自定义绘制能不能花里胡哨 一 Compose自定义 自定义 一个应用的可创造性往往离不开人们的千奇百怪想象和用户变化万千的需求 自定义