flutter 中的动画详解 全网最全 动画一篇搞定 一万四千字

news2025/1/17 6:09:59

flutter 中的动画详解 全网最全 动画一篇搞定

  • 前言
  • 一、 基础概念
  • 二、 隐式动画
  • 三、 显示动画
  • 四、 过渡
  • 五、 手势动画
  • 六、 复杂动画
  • 七、 自定义动画
  • 八、 物理动画
  • 九、 Flutter 动画库
  • 十、 动画性能和优化
  • 十一、 第三方动画库
  • 总结


前言

在这里插入图片描述

学习 Flutter 中的动画和过渡是构建流畅用户界面的关键部分之一。这里我整理了一个主要的学习路径,可以帮助你逐步掌握 Flutter 中的动画和过渡技术,希望能够帮助到你


一、 基础概念

开始之前,了解一些基本的动画和过渡概念是很重要的。学习什么是动画、过渡,以及它们在用户体验中的作用。

动画: 动画是指在一段时间内,将元素从一个状态平滑地过渡到另一个状态的过程。在用户界面中,动画可以使元素的变化显得更加生动和平滑,提升用户体验。例如,一个按钮的颜色从一种颜色过渡到另一种颜色,或者一个图标从一个位置平滑地移动到另一个位置,都是动画的例子。

过渡: 过渡是指从一个视觉状态到另一个视觉状态的平滑过程。过渡通常用于在用户界面之间切换或改变元素的状态时,使这些改变看起来更加自然和流畅。过渡可以是视觉效果,例如渐变、旋转、缩放等,也可以是元素之间的切换效果,如页面之间的过渡效果。

动画类型: 在 Flutter 中,有多种类型的动画,包括:

  • 隐式动画:当属性的值发生变化时,自动产生过渡效果,无需显式编写动画代码。
  • 显示动画:手动控制动画的进程,使用 AnimationAnimationController 来管理动画的状态。
  • 过渡动画:在页面切换或视觉元素之间进行平滑的过渡效果,如 Hero 过渡。
  • 手势动画:响应用户手势事件(如拖拽、缩放等)来触发动画效果。
  • 自定义动画:使用 CustomPainter 自绘图形、路径和动画效果,创建高度自定义的动画。

动画曲线和插值: 动画曲线和插值决定了动画的速度和变化率。曲线描述了动画值随时间的变化情况,插值定义了从起始值到结束值的过程中值的变化方式。在 Flutter 中,你可以通过 Curves 类使用内置的曲线,也可以使用 Tween 类来定义插值。

动画性能和优化: 在创建动画时,性能是一个重要的考虑因素。不合理的动画设计可能会导致应用性能下降。因此,优化动画的重绘范围、帧率和重复渲染等方面的技巧都是学习的一部分。

了解这些基础概念将为你进一步深入学习 Flutter 中的动画和过渡提供坚实的基础。在掌握这些概念后,你将能够更好地理解不同类型的动画和过渡效果,并能够更轻松地应用它们来创造出令人愉悦的用户界面。

二、 隐式动画

隐式动画(Implicit Animations)是 Flutter 中一种简单的动画形式,它通过属性的变化自动产生平滑的过渡效果,而无需显式编写大量的动画代码。这使得创建基本的动画效果变得非常容易。

在隐式动画中,你只需要改变小部件的属性值,例如颜色、位置、透明度等,Flutter 会自动在这些属性值之间创建平滑的过渡效果,以达到动画的效果。以下是隐式动画的一些常见用例和属性:

  1. AnimatedContainer: 当你改变 AnimatedContainer 的属性(如 colorwidthheightalignment 等),它会在这些属性之间产生平滑的过渡。
AnimatedContainer(
  duration: Duration(seconds: 1),
  color: _isBlue ? Colors.blue : Colors.red,
  width: _isExpanded ? 200.0 : 100.0,
  height: _isExpanded ? 200.0 : 100.0,
  child: YourChildWidget(),
);
  1. AnimatedOpacity: 通过改变 AnimatedOpacityopacity 属性,你可以创建一个透明度的平滑过渡。
AnimatedOpacity(
  duration: Duration(seconds: 1),
  opacity: _isVisible ? 1.0 : 0.0,
  child: YourChildWidget(),
);
  1. AnimatedPositioned: 使用 AnimatedPositioned 来创建小部件位置的平滑过渡。
Stack(
  children: [
    AnimatedPositioned(
      duration: Duration(seconds: 1),
      left: _isLeftAligned ? 0 : 100,
      top: _isTopAligned ? 0 : 100,
      child: YourChildWidget(),
    ),
  ],
);
  1. 其他隐式动画: 还有许多其他隐式动画小部件,如 AnimatedPaddingAnimatedAlignAnimatedDefaultTextStyle 等,它们都遵循类似的原则,通过改变属性来自动产生过渡效果。

隐式动画是学习动画的很好起点,它可以让你快速了解如何在 Flutter 中创建简单的平滑过渡效果。然而,对于更复杂的动画需求,你可能需要使用显示动画(使用 AnimationAnimationController)或自定义动画来更精细地控制动画的过程。

三、 显示动画

显示动画(Explicit Animations)是一种在 Flutter 中手动控制的动画形式,使用 AnimationAnimationController 来实现。相比隐式动画,显示动画提供了更大的灵活性,使你能够更精确地控制动画的进程、效果和交互。

以下是显示动画的主要概念和步骤:

1. Animation 和 AnimationController:

  • AnimationController 是一个控制动画的类,它管理动画的状态,如开始、停止、正向或反向播放等。
  • Animation 表示动画的当前状态,它是一个在指定范围内的可变值。动画的值会随时间变化,可以用于控制 UI 元素的属性,从而创建动画效果。

2. Tween: Tween 是一个用于定义动画插值的类,它将动画的输入范围映射到输出范围。例如,你可以使用 Tween 将动画的值从0映射到1,或从一个起始值映射到一个结束值。

3. 监听动画的值: 你可以通过监听 Animation 的值变化来更新 UI 元素,以实现动画效果。例如,你可以使用 AnimatedBuilder 将小部件与 Animation 关联,使小部件在动画值变化时重建。

AnimationController controller = AnimationController(
  vsync: this,
  duration: Duration(seconds: 2),
);

Animation<double> animation = Tween(begin: 0.0, end: 1.0).animate(controller);

controller.forward(); // 启动动画

// 使用 AnimatedBuilder 监听动画值变化
AnimatedBuilder(
  animation: animation,
  builder: (context, child) {
    return Opacity(
      opacity: animation.value,
      child: YourChildWidget(),
    );
  },
);

4. Curves 和动画曲线: 通过使用 Curves 类,你可以定义动画的变化速率,从而影响动画效果的感觉。例如,你可以使用 Curves.easeInOut 来创建一个先加速后减速的动画曲线。

5. 动画状态监听: AnimationController 提供了许多回调方法,例如 addStatusListener,可以监听动画的状态变化(如动画开始、结束、反向等)。

controller.addStatusListener((status) {
  if (status == AnimationStatus.completed) {
    // 动画完成
  } else if (status == AnimationStatus.dismissed) {
    // 动画反向播放完成
  }
});

显示动画适用于需要更精细控制和定制动画效果的情况,如在用户交互时触发动画、创建复杂的动画序列等。然而,对于一些基本的平滑过渡效果,隐式动画可能更加方便。

四、 过渡

过渡(Transitions)是指在用户界面中,从一个状态到另一个状态的平滑变化过程。在 Flutter 中,过渡通常涉及到在 UI 元素之间创建动画效果,以实现用户界面的转换。过渡可以在页面之间切换时产生平滑的效果,也可以在单个小部件内部改变属性时产生效果。

以下是一些常见的过渡场景和如何实现它们的示例:

1. 页面过渡: 页面过渡是在不同的屏幕之间创建平滑效果的方式。Flutter 提供了 PageRouteBuilder 来帮助你自定义页面过渡。

class CustomPageRoute<T> extends PageRoute<T> {
  // 实现页面过渡效果
}

Navigator.of(context).push(CustomPageRoute(builder: (context) => NextScreen()));

2. Hero 过渡: Hero 过渡用于在两个页面之间平滑地传递共享元素。例如,在一个页面中点击一个图标,可以使用 Hero 过渡将图标从当前页面过渡到目标页面。

class FirstPage extends StatelessWidget {
  
  Widget build(BuildContext context) {
    return GestureDetector(
      onTap: () {
        Navigator.of(context).push(MaterialPageRoute(
          builder: (context) => SecondPage(),
        ));
      },
      child: Hero(
        tag: 'iconTag',
        child: Icon(Icons.star),
      ),
    );
  }
}

class SecondPage extends StatelessWidget {
  
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Hero(
          tag: 'iconTag',
          child: Icon(Icons.star),
        ),
      ),
    );
  }
}

3. 小部件内部属性过渡: 你也可以在单个小部件内部改变属性以实现过渡效果,如改变颜色、位置、大小等。

class PropertyTransitionWidget extends StatefulWidget {
  
  _PropertyTransitionWidgetState createState() => _PropertyTransitionWidgetState();
}

class _PropertyTransitionWidgetState extends State<PropertyTransitionWidget> {
  double _width = 100.0;

  void _toggleSize() {
    setState(() {
      _width = _width == 100.0 ? 200.0 : 100.0;
    });
  }

  
  Widget build(BuildContext context) {
    return GestureDetector(
      onTap: _toggleSize,
      child: AnimatedContainer(
        duration: Duration(seconds: 1),
        width: _width,
        height: 100.0,
        color: Colors.blue,
      ),
    );
  }
}

过渡在改善用户界面的流畅性和用户体验方面起着关键作用。无论是页面切换、共享元素传递还是在小部件内部的属性变化,通过适当地应用过渡效果,你可以为你的应用带来更加生动和自然的感觉。

五、 手势动画

手势动画(Gesture-based Animations)是一种通过响应用户手势事件来触发和控制动画效果的技术。在 Flutter 中,你可以使用 GestureDetector 和其他手势识别器来捕获用户的手势操作,然后根据这些操作来启动、停止或改变动画效果。

以下是手势动画的主要步骤和示例:

1. 使用 GestureDetector: GestureDetector 是一个小部件,用于捕获各种手势事件,如点击、拖拽、缩放等。你可以将需要响应手势操作的小部件包裹在 GestureDetector 中。

GestureDetector(
  onTap: () {
    // 响应点击事件
  },
  onPanUpdate: (details) {
    // 响应拖拽事件
  },
  onScaleUpdate: (details) {
    // 响应缩放事件
  },
  child: YourAnimatedWidget(),
)

2. 根据手势更新动画状态: 根据捕获的手势事件,你可以更新动画的状态,例如改变动画的值、播放、暂停或反转动画。

GestureDetector(
  onPanUpdate: (details) {
    setState(() {
      // 更新动画值
      animationValue += details.delta.dx / 100;
    });
  },
  child: YourAnimatedWidget(),
)

3. 手势识别器和手势细节: 除了 GestureDetector,Flutter 还提供了许多其他手势识别器,如 DraggableDismissibleScaleGestureDetector 等,它们可以捕获特定类型的手势事件,并提供有关手势的详细信息。

Draggable(
  onDraggableCanceled: (Velocity velocity, Offset offset) {
    // 响应拖拽取消事件
  },
  child: YourAnimatedWidget(),
)

4. 结合动画效果: 将捕获的手势事件与动画效果相结合,以创建手势触发的动画效果。你可以根据手势操作更新动画的值,然后将该值应用于小部件。

double _animationValue = 0.0;

GestureDetector(
  onPanUpdate: (details) {
    setState(() {
      _animationValue += details.delta.dx / 100;
    });
  },
  child: AnimatedBuilder(
    animation: _controller,
    builder: (context, child) {
      return Transform.translate(
        offset: Offset(_animationValue * 100, 0),
        child: YourAnimatedWidget(),
      );
    },
  ),
)

手势动画允许用户以直观的方式与应用进行交互,并可以通过手势操作来触发各种动画效果,从而提升用户体验。无论是拖拽、缩放、滑动还是其他手势操作,通过合理地应用手势动画,你可以为应用添加更多的交互性和趣味性。

六、 复杂动画

复杂动画(Complex Animations)通常指涉及多个动画元素、序列动画、交错动画等,在设计和实现过程中需要更多精细控制的动画场景。这些动画通常涉及多个动画值、不同的动画控制器以及协调多个动画的同步或顺序。

以下是复杂动画的主要概念和步骤:

1. 交错动画: 交错动画是多个动画同时运行,但它们的起始时间可能有所偏移,从而创造出一种错落有致的效果。你可以使用 Interval 类来为每个动画定义起始和结束时间,从而实现交错动画。

Animation<double> animation1 = _controller.drive(Tween(begin: 0.0, end: 1.0));
Animation<double> animation2 = _controller.drive(Tween(begin: 0.0, end: 1.0));
Animation<double> animation3 = _controller.drive(Tween(begin: 0.0, end: 1.0));

Interval interval1 = Interval(0.0, 0.33);
Interval interval2 = Interval(0.33, 0.66);
Interval interval3 = Interval(0.66, 1.0);

Animation<double> anim1 = CurvedAnimation(parent: _controller, curve: interval1);
Animation<double> anim2 = CurvedAnimation(parent: _controller, curve: interval2);
Animation<double> anim3 = CurvedAnimation(parent: _controller, curve: interval3);

// 使用 anim1、anim2、anim3 分别作用于不同的动画部件

2. 链式动画: 链式动画是一种动画完成后触发下一个动画的方式。你可以使用动画控制器的状态监听器来检测动画的状态变化,然后根据状态来触发下一个动画。

_animation1.addStatusListener((status) {
  if (status == AnimationStatus.completed) {
    _controller2.forward(); // 触发第二个动画
  }
});

_animation2.addStatusListener((status) {
  if (status == AnimationStatus.completed) {
    _controller3.forward(); // 触发第三个动画
  }
});

3. 动画序列: 动画序列是一组按照一定顺序播放的动画,通常用于创建连续的动画效果。你可以使用多个 AnimationControllerCurvedAnimation,并在每个动画完成后触发下一个动画。

_animationController1.forward();
_animationController1.addStatusListener((status) {
  if (status == AnimationStatus.completed) {
    _animationController2.forward();
  }
});

_animationController2.addStatusListener((status) {
  if (status == AnimationStatus.completed) {
    _animationController3.forward();
  }
});

4. 多个动画值: 在复杂动画中,可能涉及多个动画值,你需要创建多个 Animation 并将它们应用于不同的小部件。

Animation<double> animation1 = _controller.drive(Tween(begin: 0.0, end: 1.0));
Animation<double> animation2 = _controller.drive(Tween(begin: 0.0, end: 1.0));

AnimatedBuilder(
  animation: _controller,
  builder: (context, child) {
    return Transform.translate(
      offset: Offset(animation1.value * 100, animation2.value * 100),
      child: YourAnimatedWidget(),
    );
  },
)

5. 组合动画: 组合动画是将多个动画效果结合在一起,例如旋转和缩放等。你可以使用 Transform 来组合多个变换(例如平移、旋转、缩放)以创建组合动画。

Transform(
  transform: Matrix4.rotationZ(animation1.value) * Matrix4.diagonal3Values(animation2.value, animation2.value, 1.0),
  child: YourAnimatedWidget(),
)

复杂动画需要更高级的动画控制和协调技巧,以确保多个动画之间的同步和效果达到预期。通过理解这些概念,你将能够在应用中实现更复杂、更丰富的动画场景。

七、 自定义动画

自定义动画(Custom Animations)是指通过自定义代码来实现特定的动画效果,以满足特定的设计需求。在 Flutter 中,你可以使用 CustomPainter 来绘制自定义的图形,或使用 AnimatedBuilder 封装动画逻辑,从而创建高度自定义的动画效果。

以下是自定义动画的主要步骤和示例:

1. 自绘动画(CustomPainter): 使用 CustomPainter 可以绘制自定义的图形和动画。你需要实现 CustomPainter 类并重写 paint 方法,在其中定义绘制逻辑。

class MyCustomPainter extends CustomPainter {
  
  void paint(Canvas canvas, Size size) {
    // 在这里实现自定义绘制逻辑
  }

  
  bool shouldRepaint(covariant CustomPainter oldDelegate) {
    return true; // 控制是否需要重新绘制
  }
}

class MyCustomAnimationWidget extends StatelessWidget {
  
  Widget build(BuildContext context) {
    return CustomPaint(
      painter: MyCustomPainter(),
      child: YourChildWidget(),
    );
  }
}

2. 使用 AnimatedBuilder 封装动画逻辑: AnimatedBuilder 是一个用于封装动画逻辑的小部件,它接受一个动画作为参数,并在动画值变化时重建小部件。

AnimationController _controller = AnimationController(
  vsync: this,
  duration: Duration(seconds: 2),
);

Animation<double> _animation = CurvedAnimation(
  parent: _controller,
  curve: Curves.easeInOut,
);


Widget build(BuildContext context) {
  return AnimatedBuilder(
    animation: _animation,
    builder: (context, child) {
      return Transform.scale(
        scale: _animation.value,
        child: YourChildWidget(),
      );
    },
  );
}

3. 自定义路径动画: 使用 CustomPainter,你可以绘制任何形状的路径,并在动画中改变路径的属性来实现路径动画效果。

class PathAnimationPainter extends CustomPainter {
  PathAnimationPainter(this.animation);

  final Animation<double> animation;

  
  void paint(Canvas canvas, Size size) {
    // 创建自定义路径
    Path path = createPathWithAnimation(animation.value, size);
    
    // 在画布上绘制路径
    canvas.drawPath(path, paint);
  }

  
  bool shouldRepaint(covariant CustomPainter oldDelegate) {
    return true;
  }
}

自定义动画允许你完全掌控动画效果,从绘制自定义形状、路径到创建自己的动画逻辑。无论是创建特定的图形动画还是实现独特的动画交互,自定义动画都为你提供了很大的自由度。

八、 物理动画

物理动画(Physics-based Animations)是一种模拟真实物理现象的动画效果,例如弹跳、惯性等。在 Flutter 中,你可以使用 TweenAnimationController 和物理模拟器来创建这些效果。

以下是物理动画的主要步骤和示例:

1. 使用 TweenAnimationController 与其他动画类型一样,你可以使用 Tween 来定义动画的起始值和结束值,并使用 AnimationController 来控制动画的进程。

AnimationController _controller = AnimationController(
  vsync: this,
  duration: Duration(seconds: 1),
);

Animation<double> _animation = Tween(begin: 0.0, end: 1.0).animate(_controller);

2. 使用物理模拟器(SpringSimulation): SpringSimulation 是一种物理模拟器,用于实现弹跳、惯性等物理动画效果。你可以使用 Simulation 对象来模拟动画的物理行为。

final SpringDescription _spring = SpringDescription(
  mass: 1,
  stiffness: 100,
  damping: 10,
);

final SpringSimulation _sim = SpringSimulation(_spring, 0, 1, 0);

3. 将物理模拟应用于动画: 将物理模拟与动画控制器结合,以在动画进程中应用物理效果。

_controller.animateWith(_sim);

4. 物理动画的参数调整: 调整 SpringDescription 的参数(质量、刚度、阻尼)会影响动画的效果。不同的参数设置会产生不同的弹性和惯性效果。

final SpringDescription _customSpring = SpringDescription(
  mass: 2,
  stiffness: 300,
  damping: 15,
);

5. 物理动画的应用: 物理动画通常用于模拟真实世界中的物理现象,如弹跳的按钮、惯性效果的滚动等。在应用物理动画时,你可以根据实际需求调整模拟参数,从而达到预期的效果。

物理动画可以为应用添加更真实的交互和动态效果。通过模拟物理现象,你可以让你的界面看起来更加自然,更具吸引力。

九、 Flutter 动画库

Flutter 提供了许多用于创建各种类型动画的内置库。以下是一些常用的 Flutter 动画库及其功能:

  1. flutter_animation_progress_bar 一个带有动画效果的进度条库,可以为应用添加炫酷的加载指示器。
  2. flutter_staggered_animations 提供了一组有序的动画效果,可以按照特定的顺序触发动画,用于创建复杂的动画序列。
  3. flutter_sequence_animation 用于创建复杂的序列动画,可以按照时间间隔触发一系列的动画。
  4. liquid_swipe 提供流体式的页面切换动画效果,可以创建卡片堆叠的过渡效果。
  5. flare_flutter 允许将使用 Flare 工具创建的矢量动画集成到 Flutter 应用中,用于创建高度定制的矢量动画。
  6. lottie 可以将使用 Lottie 工具创建的 After Effects 动画集成到 Flutter 应用中,用于展示复杂的矢量动画。
  7. motion_widget 提供一组预定义的动画效果,可以轻松添加不同的转场动画,如淡入淡出、滑动等。
  8. flip_panel 创建一个可以翻转的面板,用于显示数字、字母等,具有翻转动画效果。
  9. sliver_fab_animation 实现了一个 SliverAppBar 和 FloatingActionButton 的联动动画,用于在滚动时隐藏或显示 FloatingActionButton。
  10. animated_text_kit 提供一组用于创建动画文本效果的小部件,如颜色渐变、打字机效果等。
  11. flutter_animator 提供一组预定义的动画效果,可以通过简单的配置参数来应用各种动画效果。

这些是一些常用的 Flutter 动画库,它们可以帮助你更轻松地实现不同类型的动画效果,从而提升应用的用户体验。根据你的具体需求,你可以选择适合你项目的动画库,或者根据需要进行自定义开发

十、 动画性能和优化

动画性能和优化在应用开发中非常重要,因为不合理的动画设计可能会导致应用性能下降,影响用户体验。以下是一些关于动画性能和优化的重要考虑因素:

1. 选择适当的动画类型: 根据你的应用需求,选择合适的动画类型。隐式动画通常比较轻量,适合简单的过渡效果,而显示动画适用于需要精细控制的动画场景。

2. 减少动画帧率: 过高的动画帧率可能会占用过多的 CPU 和 GPU 资源,导致性能问题。根据应用的性能要求,可以将动画帧率设置为 30 或 60 帧。

3. 避免不必要的动画: 避免在屏幕上同时运行多个不必要的动画,因为这可能会导致性能下降。只有当动画对用户体验有实际价值时才应该使用。

4. 使用硬件加速: Flutter 默认开启了 GPU 硬件加速,这可以显著提高动画性能。确保你的应用配置正确,以便利用硬件加速。

5. 避免频繁重建小部件: 过于频繁地重建小部件可能会导致不必要的布局计算和绘制操作,影响性能。使用 AnimatedBuilder 等方式来限制重建。

6. 优化布局和绘制: 精简布局和绘制操作,避免在动画过程中频繁地改变布局。尽量减少复杂布局和绘制操作,以降低性能开销。

7. 使用缓存: 如果动画中的内容不经常变化,可以考虑使用缓存机制,减少不必要的重新绘制。

8. 避免动画链: 避免在一个动画结束之前立即启动下一个动画,这可能会导致性能问题。可以使用动画状态监听来确保动画顺序正确。

9. 限制动画范围: 限制动画的重绘范围,只更新动画影响的部分。例如,使用 ClipRectClipRRect 来限制动画区域。

10. 使用 ValueListenableBuilder 对于小部件内部的动画,可以使用 ValueListenableBuilder 来监听属性值的变化,避免不必要的重建。

11. 进行性能测试: 使用性能测试工具(如Flutter DevTools)来监测动画的帧率、内存使用等性能指标,以及寻找潜在的性能问题。

通过合理的动画设计和性能优化,你可以在提供出色用户体验的同时,确保应用的性能得到充分维护。

十一、 第三方动画库

在Flutter中,有许多第三方动画库可供选择,可以帮助你轻松实现各种复杂的动画效果。以下是一些常用的第三方动画库:

  1. Rive(之前称为Flare): Rive允许你使用Flare工具创建复杂的矢量动画,然后将其集成到Flutter应用中。它支持可交互的、高度定制的矢量动画。
  2. Lottie: Lottie库可以将使用Adobe After Effects创建的动画导出为JSON文件,然后在Flutter应用中播放这些动画。Lottie支持多种类型的动画效果,如形状变化、颜色变化、动画组合等。
  3. Motion: Motion是一个强大的动画库,提供了多种精美的过渡动画效果,如渐变、滑动、旋转等。它可以轻松地为小部件和页面添加动画效果。
  4. Staggered Animations: 这个库提供了一组有序的动画效果,适用于创建复杂的动画序列。你可以在小部件上按特定的顺序触发动画,从而实现交错动画效果。
  5. Smooth Page Indicator: 这个库可以帮助你创建各种平滑的页面指示器,如点状、线状、滑块等,用于指示页面之间的切换。
  6. Flip Panel: Flip Panel库可以创建可以翻转的面板,用于显示数字、字母等内容,具有翻转动画效果。
  7. Curved Navigation Bar: 这个库可以帮助你创建带有弯曲效果的底部导航栏,支持自定义颜色、图标等。
  8. Animated Text Kit: 这个库提供了多种动画文本效果,如颜色渐变、打字机效果等。适用于在文本上添加生动的动画效果。
  9. Smooth Animation: 这个库专注于创建平滑的动画效果,提供了多种动画样式,如平移、旋转、缩放等。
  10. Liquid Swipe: Liquid Swipe库可以帮助你创建流体式的页面切换动画效果,适用于创建卡片堆叠的过渡效果。

这些第三方动画库可以极大地简化复杂动画的实现过程,从而为你的应用增添更多的动态和创意。在选择第三方库时,确保它们与你的项目需求和设计风格相匹配,以便实现更好的用户体验


总结

逐步深入学习这些内容,从基础到高级,可以让你在开发 Flutter 应用时更加自信地处理各种动画和过渡效果。练习和实践是掌握这些技术的关键,因此不断尝试不同的动画场景,以及在项目中应用你学到的知识。

全篇一万四千字,希望能够帮到你,看到这里,点个赞呗

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/884957.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

问道管理:2018年以来最低水平,A股质押风险大幅缓解

2018年A股质押巅峰期之后&#xff0c;金融监管“组合拳”继续发力&#xff0c;多地政府及金融安排活跃参加纾困&#xff0c;上市公司股票质押危险化解取得本质成效。A股上市公司现在质押股数量、质押市值、质押份额均降至2018年以来最低水平。 股权质押融资是出质人将股权作为质…

CentOS系统环境搭建(十四)——CentOS7.9安装elasticsearch-head

centos系统环境搭建专栏&#x1f517;点击跳转 关于node的安装请看上一篇CentOS系统环境搭建&#xff08;十三&#xff09;——CentOS7安装nvm&#xff0c;&#x1f517;点击跳转。 CentOS7.9安装elasticsearch-head 文章目录 CentOS7.9安装elasticsearch-head1.下载2.解压3.修…

0基础学习VR全景平台篇 第85篇:智慧眼-如何分配角色的权限?

一、功能说明 角色权限&#xff0c;是指给智慧眼的所有角色成员分配具体的操作权限。 二、后台编辑界面 1、点击“添加权限”&#xff0c;选择其可操作的“权限”。注意权限只能逐项选择&#xff0c;所以如果某个角色拥有多项权限的话&#xff0c;那么需要进行多次添加。“快…

Threejs学习02——使用dat.gui实现主动控制立方体相关操作

使用dat.gui实现主动控制立方体相关操作 这是一个非常简单基础的threejs的学习应用&#xff01;在上一章学习threesj中我们实现立方体在坐标轴中来回移动&#xff0c;那都是通过我们的代码写死的效果&#xff0c;然后立方体的颜色都是通过代码写死的&#xff0c;这一章我们来给…

从零开始学习 Java:简单易懂的入门指南之MAth、System(十二)

常见API&#xff0c;MAth、System 1 Math类1.1 概述1.2 常见方法1.3 算法小题(质数)1.4 算法小题(自幂数) 2 System类2.1 概述2.2 常见方法 1 Math类 1.1 概述 tips&#xff1a;了解内容 查看API文档&#xff0c;我们可以看到API文档中关于Math类的定义如下&#xff1a; Math类…

大数据大数据架构发展史

1.背景 随着数据量的暴增和数据实时性要求越来越高&#xff0c;以及大数据技术的发展驱动企业不断升级迭代&#xff0c;传统数仓经历了以下发展过程&#xff1a;传统数仓架构 -> 离线大数据架构 -> Lambda架构 -> Kappa架构 -> 新一代实时数仓。&#xff08;大部分…

Vitis高层次综合学习——FPGA

高层次综合 什么是高层次综合&#xff1f;就是使用高级语言&#xff08;如C/C&#xff09;来编写FPGA算法程序。 在高层次综合上并不需要制定微架构决策&#xff0c;如创建状态机、数据路径、寄存器流水线等。这些细节可以留给 HLS 工具&#xff0c;通过提供输入约束&#xff…

ATX

导航 (返回顶部) 1. ATX (Advanced Technology Extended)2. 主板3. 电源 3.1 主要版本简表3.2 更换电源需要考虑的问题3.3 电源效率3.4 80 Plus 4. 退役的电源 4.1 24pin主供电接口4.2 12v的CPU供电接口4.3 12v的PCI-E供电接口4.4 SATA电源接口4.5 D型大4pin接口 1. ATX (Adv…

Android Studio Giraffe控制台乱码

这几天在使用Android Studio Giraffe进行一个App的开发&#xff0c;在项目构建的时候&#xff0c;控制台输出中文都是乱码&#xff0c;看着很不爽&#xff0c;进行了两项配置&#xff0c;中文就可以正常输出了&#xff0c;看起来就爽多了。 第一个配置&#xff1a;点击Help菜单…

冠达管理:A股利好!国家队最新出手!拜登紧急发声

号称“国家队”的大基金二期最新出手。 8月15日晚间&#xff0c;华润微公告&#xff0c;子公司润鹏半导体拟增资扩股并引进大基金二期等外部出资者&#xff0c;本次买卖完成后&#xff0c;润鹏半导体注册资本将由24亿元添加至150亿元。其间&#xff0c;大基金二期持股份额将达2…

uni-app根据经纬度逆解析详细地址

uni-app中的getLocation()方法可以获取到用户当前的地理位置&#xff08;经纬度&#xff09;、速度。 但是返回参数中的address在app中才会显示&#xff0c;小程序中不会显示&#xff0c;所以我们需要进行逆解析其地址&#xff0c;解析出它的地址信息。 1.首先要在腾讯位置服务…

解决多模块内核心模块有接口打包成jar后被依赖并调用遇到的问题(springcloud集成ruoyi.quartz)

项目准备开发个新功能&#xff0c;刚好很喜欢ruoyi写的任务调度&#xff0c;因此想到了集成ruoyi.quartz模块 &#xff0c;遇到了很多问题: 首先因为ruoyi.quartz模块依赖了ruoyi.common模块&#xff0c;因此第一步我需要把common模块一部分依赖项复制到了quartz模块内&#xf…

查看端口号被应用程序占用

打开资源监视器 找到被占用的端口&#xff0c;记住她的PID 打开任务管理器 把占用端口的程序关掉

SAP LTMC 批导创建物料

LTMC这个事务代码是HANA 版本的LSMW。其实就是一个批导工具 我们来用LTMC 来做一下物料的期初批导 1.首先在GUI中输入T-CODE &#xff1a; LTMC 2.输入你的账号密码和客户端之后会进入这个界面 3.点击CREATE 4.在下图框中的位置选择我们要进行的任务 5.download template 6.…

第六章:用FATE从零实现纵向线性回归

第六章 用FATE从零实现纵向线性回归 6.1 数据集的获取与描述6.2纵向数据集切分6.3 纵向联邦训练6.3.1 数据输入6.3.2 样本对齐6.3.3 模型训练 6.4 模型评估 代码 本章利用FATE从零开始实现一个简单的纵向线性回归模型&#xff0c;本章以实验为主。 与第5章一样&#xff0c;本章…

GEWE框架 ipad协议

GEWE框架 是一套完整的的第三方服务平台&#xff0c;包含微信API服务、企微API服务、SCRM系统定制、企微系统定制、服务类软件定制等模块&#xff0c;本文档主要讲述个微API服务相关&#xff0c;以下简称API&#xff0c;它能处理用户微信中的各种事件&#xff0c;提供了开发者…

使用VSCode的 Dev Containers 插件搭配Docker 容器进行开发环境的搭建

需要安装插件 https://marketplace.visualstudio.com/items?itemNamems-vscode-remote.remote-containers 安装Docker 这样做的好处 每一个项目可以运行一个容器&#xff0c;在容器内开发&#xff0c;相关之间node环境隔离&#xff0c;彻底解决本地包版本依赖关错乱问题共用…

日精注塑机联网

不改造程序的话&#xff0c;日精支持输出CSV和txt数据作为其他软件的接口。 改造后可以支持63协议。 在软件层面日精也有专用的软件&#xff0c;可以看到其实设备厂家提供的软件功能已经非常丰富了&#xff0c;但这类软件最大的缺点是只能自己家的机器使用&#xff0c;要想其他…

基于Pytorch构建AlexNet网络对cifar-10进行分类

AlexNet网络是CV领域最经典的网络结构之一了&#xff0c;在2012年横空出世&#xff0c;并在当年夺下了不少比赛的冠军。也是在那年之后&#xff0c;更多的更深的神经网络被提出&#xff0c;比如优秀的vgg,GoogLeNet。AlexNet和LeNet的设计非常类似&#xff0c;但AlexNet的结构比…

获取通达信股票代码接口--通达信逐笔接口(一)

通达信逐笔接口也是能获取股票的逐笔交易数据&#xff0c;但需要提前通达信逐笔接口提前安装通达信软件系统&#xff0c;打开相关的数据权限或者接口使用权限才能执行。一般执行步骤&#xff1a; 1. 初始化接口&#xff1a;在代码中引入相关的库文件并初始化获取通达信股票代码…