Flutter动画图标插件icons_animate的使用

发布于 1周前 作者 eggper 来自 Flutter

Flutter动画图标插件icons_animate的使用

icons_animate是一个用于Flutter的包,可以轻松地从两个图标创建自定义的AnimatedIcon。该包旨在让任何类型的图标都能方便地进行动画处理,而不仅仅是默认提供的少数几种。

特性

以下是一些示例动画图标:

example gif

您可以在示例项目中查看更多图标动画的例子。

开始使用

安装

要安装此包,请执行以下命令:

flutter pub add icons_animate
flutter pub get

或者手动将依赖项添加到您的pubspec.yaml文件中:

dependencies:
  icons_animate: ^0.0.2

然后在您的类中导入它:

import 'package:icons_animate/icons_animate.dart';

使用方法

这是一个简单的实现示例:

AnimateIcons(
    startIcon: Icons.add_circle,
    endIcon: Icons.add_circle_outline,
    size: 100.0,
    controller: controller,
    startTooltip: 'Icons.add_circle',
    endTooltip: 'Icons.add_circle_outline',
    splashColor: Colors.blueAccent.shade100.withAlpha(50),
    splashRadius: 24,
    onStartIconPress: () {
        print("Clicked on Add Icon");
        return true;
    },
    onEndIconPress: () {
        print("Clicked on Close Icon");
        return true;
    },
    duration: Duration(milliseconds: 500),
    startIconColor: Colors.deepPurple,
    endIconColor: Colors.deepOrange,
    clockwise: false,
)

更多详细信息请参阅示例代码

示例Demo

以下是一个完整的示例demo,展示了如何使用icons_animate包:

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

void main() {
  WidgetsFlutterBinding.ensureInitialized();
  runApp(MaterialApp(
    home: MyApp(),
    debugShowCheckedModeBanner: false,
  ));
}

class MyApp extends StatefulWidget {
  [@override](/user/override)
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  late AnimateIconController c1, c2, c3, c4, c5, c6;

  [@override](/user/override)
  void initState() {
    c1 = AnimateIconController();
    c2 = AnimateIconController();
    c3 = AnimateIconController();
    c4 = AnimateIconController();
    c5 = AnimateIconController();
    c6 = AnimateIconController();
    super.initState();
  }

  bool onEndIconPress(BuildContext context) {
    ScaffoldMessenger.of(context).showSnackBar(
      const SnackBar(
        content: Text('onEndIconPress called'),
        duration: Duration(seconds: 1),
      ),
    );
    return true;
  }

  bool onStartIconPress(BuildContext context) {
    ScaffoldMessenger.of(context).showSnackBar(
      const SnackBar(
        content: Text('onStartIconPress called'),
        duration: Duration(seconds: 1),
      ),
    );
    return true;
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      body: Builder(builder: (context) {
        return Center(
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.center,
            mainAxisSize: MainAxisSize.min,
            children: [
              Wrap(
                children: [
                  AnimateIcons(
                    startIcon: Icons.add_circle,
                    endIcon: Icons.add_circle_outline,
                    controller: c1,
                    size: 45.0,
                    curve: Curves.bounceIn,
                    onEndIconPress: () => onEndIconPress(context),
                    onStartIconPress: () => onStartIconPress(context),
                  ),
                  AnimateIcons(
                    startIcon: Icons.star,
                    endIcon: Icons.star_border,
                    controller: c2,
                    size: 45.0,
                    curve: Curves.easeIn,
                    onEndIconPress: () => onEndIconPress(context),
                    onStartIconPress: () => onStartIconPress(context),
                  ),
                  AnimateIcons(
                    startIcon: Icons.calculate,
                    endIcon: Icons.calculate_outlined,
                    controller: c3,
                    size: 45.0,
                    curve: Curves.easeOut,
                    onEndIconPress: () => onEndIconPress(context),
                    onStartIconPress: () => onStartIconPress(context),
                  ),
                  AnimateIcons(
                    startIcon: Icons.dashboard,
                    endIcon: Icons.dashboard_outlined,
                    controller: c4,
                    size: 45.0,
                    curve: Curves.elasticIn,
                    onEndIconPress: () => onEndIconPress(context),
                    onStartIconPress: () => onStartIconPress(context),
                  ),
                  AnimateIcons(
                    startIcon: Icons.handyman,
                    endIcon: Icons.handyman_outlined,
                    controller: c5,
                    size: 45.0,
                    curve: Curves.elasticOut,
                    onEndIconPress: () => onEndIconPress(context),
                    onStartIconPress: () => onStartIconPress(context),
                  ),
                  AnimateIcons(
                    startIcon: Icons.terrain_rounded,
                    endIcon: Icons.terrain_outlined,
                    controller: c6,
                    size: 45.0,
                    curve: Curves.bounceOut,
                    onEndIconPress: () => onEndIconPress(context),
                    onStartIconPress: () => onStartIconPress(context),
                  ),
                ],
              ),
              const SizedBox(height: 20.0),
              AnimateIcons(
                startIcon: Icons.play_arrow,
                endIcon: Icons.play_arrow_outlined,
                size: 45.0,
                curve: Curves.easeInOutCubic,
                controller: AnimateIconController(),
                onEndIconPress: () {
                  if (c1.isStart()) {
                    c1.animateToEnd();
                  } else if (c1.isEnd()) {
                    c1.animateToStart();
                  }
                  if (c2.isStart()) {
                    c2.animateToEnd();
                  } else if (c2.isEnd()) {
                    c2.animateToStart();
                  }
                  if (c3.isStart()) {
                    c3.animateToEnd();
                  } else if (c3.isEnd()) {
                    c3.animateToStart();
                  }
                  if (c4.isStart()) {
                    c4.animateToEnd();
                  } else if (c4.isEnd()) {
                    c4.animateToStart();
                  }
                  if (c5.isStart()) {
                    c5.animateToEnd();
                  } else if (c5.isEnd()) {
                    c5.animateToStart();
                  }
                  if (c6.isStart()) {
                    c6.animateToEnd();
                  } else if (c6.isEnd()) {
                    c6.animateToStart();
                  }
                  return true;
                },
                onStartIconPress: () {
                  if (c1.isStart()) {
                    c1.animateToEnd();
                  } else if (c1.isEnd()) {
                    c1.animateToStart();
                  }
                  if (c2.isStart()) {
                    c2.animateToEnd();
                  } else if (c2.isEnd()) {
                    c2.animateToStart();
                  }
                  if (c3.isStart()) {
                    c3.animateToEnd();
                  } else if (c3.isEnd()) {
                    c3.animateToStart();
                  }
                  if (c4.isStart()) {
                    c4.animateToEnd();
                  } else if (c4.isEnd()) {
                    c4.animateToStart();
                  }
                  if (c5.isStart()) {
                    c5.animateToEnd();
                  } else if (c5.isEnd()) {
                    c5.animateToStart();
                  }
                  if (c6.isStart()) {
                    c6.animateToEnd();
                  } else if (c6.isEnd()) {
                    c6.animateToStart();
                  }
                  return true;
                },
              ),
            ],
          ),
        );
      }),
    );
  }
}

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

1 回复

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


当然,以下是如何在Flutter项目中使用icons_animate插件来实现动画图标的示例代码。icons_animate插件提供了一系列可以动画化的图标,非常适合用于提升用户界面的交互体验。

首先,确保你已经在pubspec.yaml文件中添加了icons_animate依赖:

dependencies:
  flutter:
    sdk: flutter
  icons_animate: ^latest_version  # 替换为最新版本号

然后运行flutter pub get来安装依赖。

接下来,在你的Flutter项目中,你可以按照以下步骤使用icons_animate插件:

示例代码

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

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Icons Animate Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: Scaffold(
        appBar: AppBar(
          title: Text('Icons Animate Demo'),
        ),
        body: Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              // 使用AnimatedIconData.heartPulse
              AnimatedIcon(
                icon: AnimatedIcons.heart_pulse,
                progress: AnimationController(
                  duration: const Duration(seconds: 2),
                  vsync: Vsynchronizer(),
                )..repeat(),
                color: Colors.red,
                size: 50,
              ),
              SizedBox(height: 20),

              // 使用AnimatedIconData.menuArrow
              AnimatedIcon(
                icon: AnimatedIcons.menu_arrow,
                progress: AnimationController(
                  duration: const Duration(seconds: 2),
                  vsync: Vsynchronizer(),
                )..repeat(reverse: true),
                color: Colors.blue,
                size: 50,
              ),
              SizedBox(height: 20),

              // 使用AnimatedIconData.playPause
              AnimatedIcon(
                icon: AnimatedIcons.play_pause,
                progress: AnimationController(
                  duration: const Duration(seconds: 1),
                  vsync: Vsynchronizer(),
                )..repeat(reverse: true),
                color: Colors.green,
                size: 50,
              ),
            ],
          ),
        ),
      ),
    );
  }
}

// 自定义Vsynchronizer类,用于在没有TickerProvider的情况下创建AnimationController
class Vsynchronizer extends TickerProvider with SingleTickerProviderStateMixin {}

代码说明

  1. 依赖导入:首先导入flutter/material.darticons_animate/icons_animate.dart
  2. 主应用MyApp是根组件,包含了一个MaterialApp,其中设置了应用的主题和主页。
  3. 主页布局:主页是一个Scaffold,包含一个AppBar和一个居中的Column,用于展示动画图标。
  4. 动画图标:每个AnimatedIcon使用了一个预定义的动画图标(如AnimatedIcons.heart_pulseAnimatedIcons.menu_arrowAnimatedIcons.play_pause),并配置了AnimationController来控制动画的进度。
  5. 自定义Vsynchronizer:由于AnimatedIcon需要在TickerProvider的上下文中使用,但直接在build方法中创建AnimationController会遇到问题,因此定义了一个自定义的Vsynchronizer类,它实现了TickerProvider并混合了SingleTickerProviderStateMixin。注意,这种方法通常不推荐用于生产代码,因为它创建了一个不必要的状态管理对象。在实际应用中,最好将AnimationController移动到父组件的状态中管理。

注意事项

  • 在实际项目中,通常不建议在build方法中直接创建AnimationController,因为这会频繁地重建动画控制器,导致不必要的性能开销。建议将动画控制器提升到父组件的状态中管理。
  • 你可以根据需要调整动画图标的colorsize属性。
  • icons_animate插件提供了多种预定义的动画图标,你可以查阅其文档以获取完整的图标列表。

这样,你就可以在Flutter应用中使用icons_animate插件来实现动画图标了。

回到顶部