我有Ffltter的代码,我必须用Android(Kotlin)编写一个应用程序.如何将Flutter 画笔转换为Android Compose中的显示?

import 'dart:math' as math;
import 'dart:ui' as ui;

import 'package:flutter/material.dart';

class FaceOutline extends CustomPainter {
  final Color frameColor;

  FaceOutline(this.frameColor);

  @override
  void paint(ui.Canvas canvas, ui.Size size) {
    final Path path = Path();
    final Rect rect = Rect.fromCenter(
      center: size.center(Offset.zero),
      width: size.width * 0.95,
      height: size.width * 0.95,
    );

    path.addArc(
      rect.translate(0.0, -rect.height * 0.4),
      math.pi * 9.0 / 8.0,
      math.pi * 2.0 / 8.0,
    );
    path.addArc(
      rect.translate(0.0, -rect.height * 0.4),
      math.pi * 13.0 / 8.0,
      math.pi * 2.0 / 8.0,
    );
    path.addArc(
      rect.translate(0.0, rect.height * 0.00),
      math.pi * 1.0 / 8.0,
      math.pi * 2.0 / 8.0,
    );
    path.addArc(
      rect.translate(0.0, rect.height * 0.00),
      math.pi * 5.0 / 8.0,
      math.pi * 2.0 / 8.0,
    );

    canvas.drawPath(
      path,
      Paint()
        ..filterQuality = FilterQuality.low
        ..isAntiAlias = true
        ..strokeWidth = 8
        ..strokeCap = StrokeCap.round
        ..strokeJoin = StrokeJoin.round
        ..style = PaintingStyle.stroke
        ..color = frameColor
        ..blendMode = BlendMode.screen,
    );
  }

  @override
  bool shouldRepaint(FaceOutline oldDelegate) {
    return frameColor != oldDelegate.frameColor;
  }
}

我可以使用XML或Compose在Kotlin中显示它,但我必须知道如何在Compose视图中用原生Android编写Flutter 代码.

您可以判断代码: https://dartpad.dev/?id=b426645ba864beaa66d18212128a71cd

这是我想要的:

enter image description here

推荐答案

Jetpack组成画布的对应物如下

需要注意的事情.路径在内部,记住不要在任何重新组合时创建新实例,并且我们在路径为空时设置了一次

如果需要应用混合模式,我们应该将画布的Alpha设置为小于1f,或者使用一个层,如this answer

@Composable
private fun FaceOutlineComposable(modifier: Modifier, frameColor: Color) {

    val path = remember { Path() }

    Canvas(modifier = modifier) {

        if (path.isEmpty) {

            val canvasWidth = size.width
            val canvasHeight = size.height
            val width = size.width * 0.95f

            val rect = Rect(
                offset = Offset((canvasWidth - width) / 2, (canvasHeight - width) / 2),
                size = Size(width, width)
            )

            path.apply {
                addArcRad(
                    rect.translate(0.0f, -rect.height * 0.4f),
                    (Math.PI * 9.0 / 8.0).toFloat(),
                    (Math.PI * 2.0 / 8.0).toFloat(),
                )
                addArcRad(
                    rect.translate(0.0f, -rect.height * 0.4f),
                    (Math.PI * 13.0 / 8.0).toFloat(),
                    (Math.PI * 2.0 / 8.0).toFloat(),
                )
                addArcRad(
                    rect,
                    (Math.PI * 1.0 / 8.0).toFloat(),
                    (Math.PI * 2.0 / 8.0).toFloat(),
                )
                addArcRad(
                    rect,
                    (Math.PI * 5.0 / 8.0).toFloat(),
                    (Math.PI * 2.0 / 8.0).toFloat(),
                )
            }
        }
        
        // This is for applying blend modes
        with(drawContext.canvas.nativeCanvas) {
            val checkPoint = saveLayer(null, null)

            drawPath(
                path = path,
                color = frameColor,
                style = Stroke(
                    width = 8.dp.toPx(),
                    cap = StrokeCap.Round,
                    join = StrokeJoin.Round
                ),
                blendMode = BlendMode.Screen
            )

            restoreToCount(checkPoint)
        }
    }
}

用法

FaceOutlineComposable(
    modifier = Modifier
        .fillMaxSize()
        .background(Color(0xff12252a)),
    frameColor = Color(0xff2196F3)
)

结果

Flutter相关问答推荐

飘动的文本用/字符绕转

如何更改默认应用程序启动器/启动屏幕

Fighter:基于ChangeNotifier状态动态更新AppBar中的图标

如何实现Flutter 梳理机图像的小量移动

为什么我的页面控制器在使用Riverpod时没有更改我的页面视图?

BaseInputfield和Textfield有什么不同?

Flutter-Riverpod:如何只从提供者读取一次值

Flutter在CustomPainter的右上角和左上角添加了2条曲线

NotifierProvider 每次更新都会重新构建并且值不更新

Flutter:注册 UI 出现 UI 问题(将注册框提升到顶部并向电话号码 pin 码添加一个框)

Flutter中如何实现带有变化图标的浮动操作按钮?

使 Row 中的元素保持在中间的空间,如果它们太大,则将它们包裹起来

Flutter Flame OS 错误:使用音频文件 .wav 时出现该进程无法访问该文件,因为它正被另一个进程使用

如何设置行中项目之间的空格相等?

如何从另一个页面访问 Firebase 值?

Flutter:为什么我的 listTile colored颜色 被容器 colored颜色 覆盖了?

如何为文本主题设置多种 colored颜色 ?

Firebase 中的查询限制 - .orderBy() 错误

我已经删除了我的 .android 密钥库,但我没有使用它,如何生成一个新的?

阴影效果只出现在一张卡片的左边 在Flutter 中?