Flutter动画控制插件curved_animation_controller的使用

Flutter动画控制插件curved_animation_controller的使用

CurvedAnimationController 是一个简单的工具,用于在 Flutter 中使用带有曲线的 AnimationController

开始使用

在您的 Flutter 项目中添加依赖项:

$ flutter pub add curved_animation_controller

或者在 pubspec.yaml 文件中添加:

dependencies:
  curved_animation_controller: ^1.1.0+1

或者从 GitHub 获取:

dependencies:
  curved_animation_controller:
    git: https://github.com/salkuadrat/curved_animation_controller.git

然后运行 flutter pub get

示例

在 GitHub 的 example 文件夹 中有一个很好的示例项目。您可以查看它以学习如何使用 Curved Animation Controller

使用方法

以下是一个常见的代码片段,用于实现带有曲线的动画。

AnimationController _controller = AnimationController(
  vsync: this, 
  duration: Duration(milliseconds: 300),
);

Animation _animation = Tween(begin: 0.0, end: 1.0).animate(CurvedAnimation(
  parent: _controller, curve: Curves.easeInOut,
));

_controller.addListener(() => setState(() {}));

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

// 应用动画
Opacity(
  opacity: _animation.value,
  child: child,
)

使用 CurvedAnimationController 可以使代码更简洁:

CurvedAnimationController _animation = CurvedAnimationController(
  vsync: this, duration: Duration(milliseconds: 300),
  curve: Curves.easeInOut,
);

_animation.addListener(() => setState(() {}));

// 启动动画
_animation.start();

// 应用动画
Opacity(
  opacity: _animation.value,
  child: child,
)

我们还可以使用自定义的 Tween

CurvedAnimationController<Color> _animation = CurvedAnimationController<Color>.tween(
  ColorTween(begin: Colors.pink, end: Colors.teal),
  Duration(milliseconds: 300),
  curve: Curves.easeInCubic,
  vsync: this,
);

_animation.addListener(() => setState(() {}));

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

// 应用动画
Container(
  color: _animation.value,
  child: child,
)

别忘了正确地释放控制器:

[@override](/user/override)
void dispose() {
  _animation.dispose();
  super.dispose();
}

可用构造函数

CurvedAnimationController(
  begin: begin,
  end: end,
  vsync: vsync,
  curve: curve,
  duration: duration,
  reverseCurve: reverseCurve,
  reverseDuration: reverseDuration,
  animationBehavior: animationBehavior,
  debugLabel: debugLabel,
);
CurvedAnimationController.tween(
  tween, // 例如: ColorTween(begin: Colors.pink, end: Colors.teal)
  duration,
  vsync: vsync,
  curve: curve,
  reverseCurve: reverseCurve,
  reverseDuration: reverseDuration,
  animationBehavior: animationBehavior,
  debugLabel: debugLabel,
);
CurvedAnimationController.sequence(
  sequence, // 序列列表 (List<SequenceItem>)
  duration,
  vsync: vsync,
  curve: curve,
  reverseCurve: reverseCurve,
  reverseDuration: reverseDuration,
  animationBehavior: animationBehavior,
  debugLabel: debugLabel,
);
CurvedAnimationController.tweenSequence(
  sequence, // TweenSequence
  duration,
  vsync: vsync,
  curve: curve,
  reverseCurve: reverseCurve,
  reverseDuration: reverseDuration,
  animationBehavior: animationBehavior,
  debugLabel: debugLabel,
);

可用方法

启动动画:

start()

或:

forward()

启动反向动画:

reverse()

停止动画:

stop()

使用惯性效果启动动画:

fling()

动画到特定目标值:

animateTo()

动画回特定目标值:

animateBack()

重置动画:

reset()

释放动画控制器:

dispose()

添加动画监听器:

addListener()

移除动画监听器:

removeListener()

添加动画状态监听器:

addStateListener()

移除动画状态监听器:

removeStateListener()

通知所有监听器:

notifyListeners()

示例代码

以下是来自 example/lib/main.dart 的示例代码:

import 'package:example/flip_drawer.dart';
import 'package:example/page.dart';
import 'package:example/shared.dart';
import 'package:example/slide_drawer.dart';
import 'package:flutter/material.dart';

void main() {
  runApp(App());
}

class App extends StatefulWidget {
  static _AppState? of(BuildContext context) =>
      context.findAncestorStateOfType<_AppState>();

  [@override](/user/override)
  _AppState createState() => _AppState();
}

class _AppState extends State<App> {
  String _title = 'Curved Animation';
  Key _key = UniqueKey();

  restart() {
    setState(() {
      _key = UniqueKey();
    });
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      key: _key,
      title: 'Curved Animation Controller Demo',
      theme: ThemeData(
        primarySwatch: Colors.teal,
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      home: isFlipDrawer
          ? FlipDrawer(title: _title, drawer: MenuDrawer(), child: HomePage())
          : SlideDrawer(drawer: MenuDrawer(), child: HomePage(title: _title)),
    );
  }
}

class MenuDrawer extends StatelessWidget {
  BoxDecoration get _gradient =>
      BoxDecoration(
        gradient: LinearGradient(
          begin: Alignment.topLeft,
          end: Alignment.bottomRight,
          stops: [0.0, 1.0],
          colors: [
            Color(0xFF43CEA2),
            Color(0xFF1D6DBD),
          ],
        ),
      );

  BoxDecoration get _color =>
      BoxDecoration(
        color: Colors.teal[500],
      );

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Material(
      shadowColor: Colors.transparent,
      borderOnForeground: false,
      child: Container(
        decoration: isSlideDrawer ? _gradient : _color,
        child: SafeArea(
          child: Theme(
            data: ThemeData(brightness: Brightness.dark),
            child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              crossAxisAlignment: CrossAxisAlignment.start,
              mainAxisSize: MainAxisSize.max,
              children: [
                if (!isSlideDrawer)
                  ListTile(
                    leading: Icon(Icons.adjust),
                    title: Text('Slide Drawer'),
                    onTap: () {
                      type = DrawerType.slide;
                      App.of(context)!.restart();
                    },
                  ),
                if (!isFlipDrawer)
                  ListTile(
                    leading: Icon(Icons.adjust),
                    title: Text('Flip Drawer'),
                    onTap: () {
                      type = DrawerType.flip;
                      App.of(context)!.restart();
                    },
                  ),
                ListTile(
                  leading: Icon(Icons.rss_feed),
                  title: Text('News'),
                ),
                ListTile(
                  leading: Icon(Icons.favorite_border),
                  title: Text('Favourites'),
                ),
                ListTile(
                  leading: Icon(Icons.map),
                  title: Text('Map'),
                ),
                ListTile(
                  leading: Icon(Icons.settings),
                  title: Text('Settings'),
                ),
                ListTile(
                  leading: Icon(Icons.person_outline),
                  title: Text('Profile'),
                ),
              ],
            ),
          ),
        ),
      ),
    );
  }
}

更多关于Flutter动画控制插件curved_animation_controller的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter动画控制插件curved_animation_controller的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


curved_animation_controller 是 Flutter 中的一个第三方插件,它扩展了 Flutter 自带的 AnimationController,使其支持更复杂的曲线动画控制。通过 CurvedAnimationController,你可以更灵活地定义动画的曲线和持续时间。

安装插件

首先,你需要在 pubspec.yaml 文件中添加 curved_animation_controller 依赖:

dependencies:
  flutter:
    sdk: flutter
  curved_animation_controller: ^0.1.0

然后运行 flutter pub get 来安装插件。

基本使用

以下是一个简单的例子,展示了如何使用 CurvedAnimationController 来控制动画。

import 'package:flutter/material.dart';
import 'package:curved_animation_controller/curved_animation_controller.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: Text('CurvedAnimationController Example')),
        body: Center(
          child: CurvedAnimationExample(),
        ),
      ),
    );
  }
}

class CurvedAnimationExample extends StatefulWidget {
  @override
  _CurvedAnimationExampleState createState() => _CurvedAnimationExampleState();
}

class _CurvedAnimationExampleState extends State<CurvedAnimationExample>
    with SingleTickerProviderStateMixin {
  late CurvedAnimationController _controller;

  @override
  void initState() {
    super.initState();
    _controller = CurvedAnimationController(
      vsync: this,
      duration: Duration(seconds: 2),
      curve: Curves.easeInOut, // 使用内置曲线
      reverseCurve: Curves.easeInOut, // 反向动画的曲线
    )..repeat(reverse: true); // 循环播放动画
  }

  @override
  void dispose() {
    _controller.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return AnimatedBuilder(
      animation: _controller,
      builder: (context, child) {
        return Transform.scale(
          scale: _controller.value, // 使用当前的动画值
          child: Container(
            width: 100,
            height: 100,
            color: Colors.blue,
          ),
        );
      },
    );
  }
}

关键点解释

  1. CurvedAnimationController: 这是 curved_animation_controller 提供的一个类,它扩展了 AnimationController,支持更复杂的曲线动画控制。

  2. vsync: 这是 TickerProvider,通常使用 SingleTickerProviderStateMixin 来提供 vsync

  3. duration: 动画的总持续时间。

  4. curve: 定义动画的曲线。你可以使用 Flutter 内置的曲线,如 Curves.easeInOut,或者自定义曲线。

  5. reverseCurve: 定义反向动画的曲线。如果未指定,默认使用 curve

  6. repeat: 设置动画是否循环播放。reverse: true 表示动画在正向和反向之间循环。

  7. AnimatedBuilder: 用于根据动画的值更新 UI。

自定义曲线

除了使用内置的曲线,你还可以自定义曲线。例如:

_controller = CurvedAnimationController(
  vsync: this,
  duration: Duration(seconds: 2),
  curve: Cubic(0.42, 0.0, 0.58, 1.0), // 自定义三阶贝塞尔曲线
  reverseCurve: Cubic(0.42, 0.0, 0.58, 1.0),
)..repeat(reverse: true);
回到顶部