Flutter CustomPaint详解

CustomPaint是Flutter中一个非常强壮的绘图组件,它能够让咱们自由地制作各种形状和图画,以满意咱们的各种需求。在本文中,咱们将具体介绍Flutter CustomPaint的作用、参数、功用和运用场景。

CustomPaint是什么?

CustomPaint是一个能够自定义制作的组件。咱们能够在它上面制作各种形状和图画,包括直线、矩形、圆形、曲线等等。它是Flutter中最基础、最灵敏的绘图组件之一。

CustomPaint的作用

CustomPaint的作用非常广泛。咱们能够运用它来完成各式各样的绘图需求,比方:

  • 制作自定义图标
  • 制作自定义布景
  • 制作自定义进度条
  • 制作自定义曲线
  • 制作自定义动画

CustomPaint有哪些参数

CustomPaint有许多参数,下面是一些比较常用的参数:

  • size:CustomPaint的巨细。
  • painter:CustomPainter目标,用于制作CustomPaint的内容。
  • foregroundPainter:CustomPainter目标,用于在CustomPaint内容之上制作内容。
  • child:CustomPaint子节点。
  • isComplex:是否复杂。
  • willChange:是否会发生变化。

其间,最重要的参数是painter。咱们需求经过承继CustomPainter类来完成咱们自己的制作逻辑。在CustomPainter中,咱们需求完成两个办法:paint和shouldRepaint。paint办法用于完成具体的制作逻辑,而shouldRepaint办法用于判别是否需求重新制作。

按照运用场景举例说明怎么运用它

下面咱们来看一些具体的运用场景,以及怎么运用CustomPaint来完成它们。

制作自定义图标

假如咱们需求一个自定义的图标,能够运用CustomPaint来完成它。首要,咱们需求承继CustomPainter类,并在paint办法中完成具体的制作逻辑。比方,下面是一个制作心形图标的比方:

class HeartIconPainter extends CustomPainter {
  @override
  void paint(Canvas canvas, Size size) {
    final paint = Paint()
      ..color = Colors.red
      ..style = PaintingStyle.fill;
    final path = Path()
      ..moveTo(size.width / 2, size.height / 5)
      ..cubicTo(size.width / 3, 0, 0, size.height / 3.5, size.width / 2, size.height)
      ..cubicTo(size.width, size.height / 3.5, size.width * 2 / 3, 0, size.width / 2, size.height / 5);
    canvas.drawPath(path, paint);
  }
  @override
  bool shouldRepaint(CustomPainter oldDelegate) => false;
}

然后,咱们能够将HeartIconPainter目标传递给CustomPaint组件,来显现咱们自定义的图标:

CustomPaint(
  painter: HeartIconPainter(),
),

显现的作用应该是这样的

custompaint_heart.png

制作自定义布景

假如咱们需求一个自定义的布景,能够运用CustomPaint来完成它。首要,咱们需求承继CustomPainter类,并在paint办法中完成具体的制作逻辑。比方,下面是一个制作突变布景的比方:

class GradientBackgroundPainter extends CustomPainter {
  @override
  void paint(Canvas canvas, Size size) {
    final rect = Rect.fromLTWH(0.0, 0.0, size.width, size.height);
    final gradient = LinearGradient(
      begin: Alignment.topCenter,
      end: Alignment.bottomCenter,
      colors: [
        Colors.blue.shade800,
        Colors.blue.shade200,
      ],
    );
    final paint = Paint()..shader = gradient.createShader(rect);
    canvas.drawRect(rect, paint);
  }
  @override
  bool shouldRepaint(CustomPainter oldDelegate) => false;
}

然后,咱们能够将GradientBackgroundPainter目标传递给CustomPaint组件的foregroundPainter参数,来显现咱们自定义的布景:

CustomPaint(
  foregroundPainter: GradientBackgroundPainter(),
),

显现的作用应该是这样的

custompaint_background.png

4.3 制作自定义进度条

假如咱们需求一个自定义的进度条,能够运用CustomPaint来完成它。首要,咱们需求承继CustomPainter类,并在paint办法中完成具体的制作逻辑。比方,下面是一个制作圆形进度条的比方:

class CircleProgressBarPainter extends CustomPainter {
  final double progress;
  CircleProgressBarPainter(this.progress);
  @override
  void paint(Canvas canvas, Size size) {
    final paint = Paint()
      ..color = Colors.blue
      ..style = PaintingStyle.stroke
      ..strokeWidth = 10;
    final center = Offset(size.width / 2, size.height / 2);
    final radius = min(size.width / 2, size.height / 2) - paint.strokeWidth / 2;
    canvas.drawCircle(center, radius, paint);
    final progressPaint = Paint()
      ..color = Colors.blue
      ..style = PaintingStyle.stroke
      ..strokeWidth = 10;
    final progressAngle = 2 * pi * progress;
    canvas.drawArc(Rect.fromCircle(center: center, radius: radius), -pi / 2,
        progressAngle, false, progressPaint);
  }
  @override
  bool shouldRepaint(CustomPainter oldDelegate) => false;
}

然后,咱们能够将CircleProgressBarPainter目标传递给CustomPaint组件,并经过progress参数来控制进度:

CustomPaint(
  painter: CircleProgressBarPainter(0.6),
),

显现的作用应该是这样的

custompaint_circleprogress.png

4.4 制作自定义曲线

假如咱们需求一个自定义的曲线,能够运用CustomPaint来完成它。首要,咱们需求承继CustomPainter类,并在paint办法中完成具体的制作逻辑。比方,下面是一个制作波浪曲线的比方:

class WaveCurvePainter extends CustomPainter {
  @override
  void paint(Canvas canvas, Size size) {
    final paint = Paint()
      ..color = Colors.blue
      ..style = PaintingStyle.fill;
    final path = Path()
      ..moveTo(0, size.height * 0.75)
      ..quadraticBezierTo(
          size.width * 0.25, size.height * 0.65, size.width * 0.5, size.height * 0.75)
      ..quadraticBezierTo(
          size.width * 0.75, size.height * 0.85, size.width, size.height * 0.75)
      ..lineTo(size.width, size.height)
      ..lineTo(0, size.height)
      ..close();
    canvas.drawPath(path, paint);
  }
  @override
  bool shouldRepaint(CustomPainter oldDelegate) => false;
}

然后,咱们能够将WaveCurvePainter目标传递给CustomPaint组件,来显现咱们自定义的曲线:

CustomPaint(
  painter: WaveCurvePainter(),
),

4.5 制作自定义动画

显现的作用应该是这样的

custompaint_waveline.png

假如咱们需求一个自定义的动画作用,能够运用CustomPaint来完成它。首要,咱们需求承继CustomPainter类,并在paint办法中完成具体的制作逻辑。比方,下面是一个制作跳动动画的比方:

class JumpingBallPainter extends CustomPainter with ChangeNotifier {
  double _value = -1.0;
  void jump() {
    _value = -1.0;
    notifyListeners();
    Future.delayed(Duration(milliseconds: 100), () {
      _value = 1.0;
      notifyListeners();
    });
    Future.delayed(Duration(milliseconds: 200), () {
      _value = -1.0;
      notifyListeners();
    });
    Future.delayed(Duration(milliseconds: 300), () {
      _value = 0.0;
      notifyListeners();
    });
  }
  @override
  void paint(Canvas canvas, Size size) {
    final paint = Paint()..color = Colors.blue;
    final ballSize = min(size.width, size.height) / 2;
    final ballCenter =
        Offset(size.width / 2, size.height / 2 + ballSize * _value);
    canvas.drawCircle(ballCenter, ballSize, paint);
  }
  @override
  bool shouldRepaint(CustomPainter oldDelegate) => true;
}

然后,咱们能够将JumpingBallPainter目标传递给CustomPaint组件,并经过调用jump办法来触发动画作用:

final jumpingBallPainter = JumpingBallPainter();
CustomPaint(
  painter: jumpingBallPainter,
),
GestureDetector(
  onTap: () {
    jumpingBallPainter.jump();
  },
),

显现的作用应该是这样的

custompaint_jumpball.gif

以上便是Flutter CustomPaint的具体介绍。期望经过本文的介绍,我们能够更好地理解Flutter CustomPaint的作用、参数、功用和运用场景,并能够灵敏地运用它来满意各种需求。