Flutter如何绘制半圆形(扇形)

27

如何画出像这样的半圆?

输入图像描述

代码:

class DrawHalfCircleClipper extends CustomClipper<Path> {
  @override
  Path getClip(Size size) {
    final Path path = new Path();
    ...
    return path;
  }
  @override
  bool shouldReclip(CustomClipper<Path> oldClipper) {
    return true;
  }
6个回答

36
创建一个名为MyArcStatelessWidget,它接受一个diameter参数。
import 'dart:math' as math;

class MyArc extends StatelessWidget {
  final double diameter;

  const MyArc({super.key, this.diameter = 200});

  @override
  Widget build(BuildContext context) {
    return CustomPaint(
      painter: MyPainter(),
      size: Size(diameter, diameter),
    );
  }
}


// This is the Painter class
class MyPainter extends CustomPainter {
  @override
  void paint(Canvas canvas, Size size) {
    Paint paint = Paint()..color = Colors.blue;
    canvas.drawArc(
      Rect.fromCenter(
        center: Offset(size.height / 2, size.width / 2),
        height: size.height,
        width: size.width,
      ),
      math.pi,
      math.pi,
      false,
      paint,
    );
  }

  @override
  bool shouldRepaint(CustomPainter oldDelegate) => false;
}

用法:

@override
Widget build(BuildContext context) {
  return Scaffold(
    appBar: AppBar(),
    body: MyArc(diameter: 300),
  );
}

我们如何将LinearGradient作为颜色添加到绘图类中? - user2511882
2
你需要在 Paint 对象上使用 Shader - CopsOnRoad
有什么想法可以让我把它翻转过来,使圆形的一面朝下吗? - L.Goyal
@L.Goyal 在 drawArc 的第三个参数中使用 -math.pi - CopsOnRoad

11
Container(
    decoration: const BoxDecoration(
      color: Colors.black,
      borderRadius: BorderRadius.only(
        bottomLeft: Radius.circular(100),
        bottomRight: Radius.circular(100),
      ),

使用此代码可以制作半圆形。


1
你必须在发送代码之前重新格式化它。 - DolDurma
1
抱歉,我对此还很新。 - sandwhale
目前你的回答不够清晰,请编辑并添加更多细节以帮助其他人理解它如何回答所提出的问题。你可以在帮助中心找到有关如何撰写好答案的更多信息。 - Community
谢谢你,谢谢你。 - sandwhale
请修复代码。许多报告表明,人们仅仅看着它就患上了癌症和糖尿病。 - stackunderflow

5
创建一个从CustomClipper派生的类,使用arcToPoint方法绘制圆形,并使用ClipPath小部件。下面是实现它的代码:
ClipPath(
      clipper: CustomClip(),
      child: Container(
        width: 200,
        height: 100,
        color: Colors.blue,
      ),
    ),

    class CustomClip extends CustomClipper<Path> {
      @override
      Path getClip(Size size) {
        double radius = 100;
    
        Path path = Path();
        path
          ..moveTo(size.width / 2, 0)
          ..arcToPoint(Offset(size.width, size.height),
              radius: Radius.circular(radius))
          ..lineTo(0, size.height)
          ..arcToPoint(
            Offset(size.width / 2, 0),
            radius: Radius.circular(radius),
          )
          ..close();
    
        return path;
      }
    
      @override
      bool shouldReclip(covariant CustomClipper<Path> oldClipper) {
        return true;
      }
    }

3

更新:你只需要一个容器,非常简单:

Container(
                          decoration: BoxDecoration(
                            borderRadius: BorderRadius.only(
                                bottomLeft: Radius.circular(100),
                                topLeft: Radius.circular(100)),
                            color: Colors.red,
                            shape: BoxShape.rectangle,
                          ),
                          height: 35,
                          width: 35,
                        ),

这里是一个使用 Stack 的简单代码。您可以使用矩形和圆形轻松生成半圆。使用 BoxDecoration(shape:) 重新塑造容器。

Stack(
   children: [
        Align(
           alignment: Alignment.center,
           child: Container(
                height: 35,
                          width: 35,
                          decoration: BoxDecoration(
                            color: Colors.red,
                            shape: BoxShape.circle,
                          ),
                        ),
                      ),
                      Align(
                        alignment: Alignment.centerLeft,
                        child: Container(
                          decoration: BoxDecoration(
                            color: Colors.red,
                            shape: BoxShape.rectangle,
                          ),
                          height: 35,
                          width: 35,
                        ),
                      ),
                    ],
                  ),

3

使用简单的实现方式(不是最佳实践),您可以在一行中绘制两个具有相同宽度和高度的容器, 并为每个容器提供 BoxDectoration => BorderRadius,如下所示:

这不是最佳实现方法,但它可以正常工作。

Row(children: [

          Container(
            decoration: BoxDecoration(
              borderRadius: BorderRadius.only(topRight: Radius.circular(200),),
            color: Colors.blue[300],
            ),
            width: 200,
            height: 200,
            ),
            Container(
            decoration: BoxDecoration(
              borderRadius: BorderRadius.only(topLeft: Radius.circular(200),),
            color: Colors.blue[300],
            ),
            width: 200,
            height: 200,
            )

], ),


确保宽度=高度=圆形边框半径。 - Mohammed Adel

0

这个会有效,你可以更改尺寸,但确保高度为borderRadius的一半,宽度等于borderRadius。

Container(
height: 50,
         width:100,
    decoration: const BoxDecoration(
      color: Colors.black,
      borderRadius: BorderRadius.only(
        bottomLeft: Radius.circular(100),
        bottomRight: Radius.circular(100),
      ))),

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接