flutter 动画和绘制

在 Flutter 中实现动画涉及到多个概念和组件。Flutter 提供了强大的动画库,使得创建流畅、富有表现力的动画变得相对简单。以下是实现动画的几个基本步骤:

1. 选择合适的动画类型

Flutter 中有两种主要类型的动画:

  • Tween 动画 :用于简单的从一个值过渡到另一个值的动画。
  • 物理模拟动画 :用于模拟物理现象,如弹簧、重力等。

2. 使用 AnimationController

AnimationController 是一个特殊的 Animation 对象,在给定的 Duration 内生成新值。

final AnimationController controller = AnimationController(
  duration: const Duration(seconds: 2),
  vsync: this, // 需要一个 TickerProvider 类型的对象
);

这里,vsync 参数防止屏幕外动画消耗不必要的资源。

3. 创建 Tween

Tween 对象定义了动画的开始和结束值。

final Tween<double> tween = Tween(begin: 0.0, end: 1.0);

4. 连接 Tween 和 Controller

通过调用 Tweenanimate 方法并传递 Controller 来创建 Animation 对象。

final Animation<double> animation = tween.animate(controller);

5. 监听动画状态

你可以监听动画的每一帧以及状态变化。

animation.addListener(() {
  setState(() {
    // 状态改变时重新构建 widget
  });
});

animation.addStatusListener((status) {
  if (status == AnimationStatus.completed) {
    // 动画完成时的操作
  }
});

6. 在 Widget 中使用 Animation

使用 AnimatedBuilderAnimatedWidget 将动画应用于 widget。

AnimatedBuilder(
  animation: animation,
  builder: (context, child) {
    return Opacity(
      opacity: animation.value,
      child: child,
    );
  },
  child: MyWidget(), // 需要动画的 Widget
);

7. 控制动画

最后,使用 controller 来控制动画的播放、停止等。

controller.forward(); // 开始动画

注意事项

  • 资源管理 :确保在 widget 销毁时释放 AnimationController
  • 性能 :对于不在屏幕上的动画,使用 vsync 停止其消耗资源。
  • 组合动画 :可以将多个动画和动画控制器组合以创建复杂的动画效果。

通过这些步骤,你可以在 Flutter 应用中创建各种动态和吸引人的动画效果,增强用户体验。

在 Flutter 中,有许多内置的动画组件,可以用来实现透明度动画、缩放动画、位置移动动画等效果。下面列出了一些常用的动画组件及其用途:

1. Opacity 动画

Opacity 组件用于调整子组件的不透明度。

Opacity(
  opacity: 0.5, // 透明度,0.0 完全透明,1.0 完全不透明
  child: MyWidget(),
)

2. Scale 动画

ScaleTransition 用于根据动画值缩放子组件。

ScaleTransition(
  scale: animation, // Animation<double> 类型
  child: MyWidget(),
)

3. 位置移动动画

  • PositionedTransition :用于相对于 Stack 的位置变化动画。

    PositionedTransition(
      rect: animation, // Animation<RelativeRect> 类型
      child: MyWidget(),
    )
    
    

    SlideTransition :用于沿指定方向滑动子组件的动画。

    SlideTransition(
      position: animation, // Animation<Offset> 类型
      child: MyWidget(),
    )
    
    

4. 大小变化动画

SizeTransition 可以使子组件的大小沿着指定轴线变化。

SizeTransition(
  sizeFactor: animation, // Animation<double> 类型
  axis: Axis.vertical, // 变化轴线
  child: MyWidget(),
)

5. 旋转动画

RotationTransition 可以使子组件根据动画值旋转。

RotationTransition(
  turns: animation, // Animation<double> 类型
  child: MyWidget(),
)

6. 渐变动画

AnimatedOpacityAnimatedCrossFade 用于创建渐变效果。

  • AnimatedOpacity

    AnimatedOpacity(
      opacity: 0.5,
      duration: Duration(seconds: 1),
      child: MyWidget(),
    )
    
    

    AnimatedCrossFade

    AnimatedCrossFade(
      firstChild: MyFirstWidget(),
      secondChild: MySecondWidget(),
      crossFadeState: CrossFadeState.showFirst,
      duration: Duration(seconds: 1),
    )
    
    

7. 容器变化动画

AnimatedContainer 在容器属性变化时自动创建动画效果。

AnimatedContainer(
  width: 200.0,
  height: 200.0,
  color: Colors.blue,
  duration: Duration(seconds: 1),
  child: MyWidget(),
)

8. 列表项动画

AnimatedList 可用于动画列表项的插入和移除。

AnimatedList(
  initialItemCount: _items.length,
  itemBuilder: (context, index, animation) {
    return SlideTransition(
      position: animation.drive(myOffset), // 自定义 Offset 动画
      child: MyListItem(_items[index]),
    );
  },
)

CustomPaint绘制

CustomPaint 是 Flutter 中一个非常强大的 widget,用于实现自定义的绘制操作。它通常与 CustomPainter 类一起使用,后者定义了在画布(Canvas)上绘制的具体内容。你可以使用 CustomPaint 来绘制复杂的形状、图案或任何其他自定义的绘图。

基本用法

  1. 创建 CustomPainter 类 :首先,你需要创建一个继承自 CustomPainter 的类,并重写 paintshouldRepaint 方法。

    class MyCustomPainter extends CustomPainter {
      @override
      void paint(Canvas canvas, Size size) {
        // 使用 canvas 绘制
        var paint = Paint()
          ..color = Colors.blue
          ..strokeWidth = 5;
    
        // 绘制一个简单的线条
        canvas.drawLine(Offset(0, 0), Offset(size.width, size.height), paint);
      }
    
      @override
      bool shouldRepaint(covariant CustomPainter oldDelegate) {
        // 返回值决定是否需要重绘
        return false;
      }
    }
    
    

    使用 CustomPaint widget :然后,在你的 widget 树中使用 CustomPaint 并将你的 CustomPainter 实例传递给它。

    CustomPaint(
      painter: MyCustomPainter(),
      child: Container(
        width: 300,
        height: 300,
      ),
    )
    
    

注意事项

  • 性能 :自定义绘制可能会对性能产生影响,特别是在复杂的绘制或大量重绘时。确保你的 shouldRepaint 方法正确实现,以避免不必要的重绘。
  • 尺寸CustomPaint 的尺寸默认是它的父 widget 的尺寸。如果它有一个 child,那么它的尺寸会适应这个 child 的尺寸,除非你提供了 size 参数。
  • 画布坐标 :Canvas 的 (0, 0) 坐标位于 CustomPaint widget 的左上角。

Paint 对象在 Flutter 中用于描述如何绘制形状(线条、圆形、矩形等)。它包含了各种属性来定义绘图样式,如颜色、笔画宽度、填充类型等。下面是一些 Paint 的用法示例,展示了如何使用不同的属性来创建各种绘图效果。

示例 1:基本线条绘制

class LinePainter extends CustomPainter {
  @override
  void paint(Canvas canvas, Size size) {
    final paint = Paint()
      ..color = Colors.blue
      ..strokeWidth = 5.0;

    canvas.drawLine(Offset(0, 0), Offset(size.width, size.height), paint);
  }

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

示例 2:绘制带有边框的圆

class CirclePainter extends CustomPainter {
  @override
  void paint(Canvas canvas, Size size) {
    final paint = Paint()
      ..color = Colors.red
      ..style = PaintingStyle.stroke
      ..strokeWidth = 4.0;

    canvas.drawCircle(size.center(Offset.zero), 50.0, paint);
  }

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

在这个例子中,Paint 被配置为红色,样式为 PaintingStyle.stroke,这意味着圆是空心的,仅绘制边框。

示例 3:渐变填充

class GradientPainter extends CustomPainter {
  @override
  void paint(Canvas canvas, Size size) {
    final Rect rect = Offset.zero & size;
    final Gradient gradient = LinearGradient(
      colors: [Colors.red, Colors.blue],
    );

    final paint = Paint()
      ..shader = gradient.createShader(rect);

    canvas.drawRect(rect, paint);
  }

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

这个例子展示了如何使用线性渐变来填充一个矩形。Paintshader 属性设置了一个 LinearGradient

示例 4:绘制虚线

class DashedLinePainter extends CustomPainter {
  @override
  void paint(Canvas canvas, Size size) {
    final paint = Paint()
      ..color = Colors.green
      ..strokeWidth = 5.0
      ..style = PaintingStyle.stroke;

    var max = size.width;
    var dashWidth = 10.0;
    var dashSpace = 5.0;
    double startX = 0;

    while (startX < max) {
      canvas.drawLine(Offset(startX, 0), Offset(startX + dashWidth, 0), paint);
      startX += dashWidth + dashSpace;
    }
  }

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

这个例子中,Paint 用于绘制一系列短线段,从而形成虚线的效果。

封装的flutter基础框架: https:/gitee.com/kuaipai/jd_flutter,你可以参考

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容