Flutter动画列表插件simple_animated_staggered的使用

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

Flutter动画列表插件simple_animated_staggered的使用

简介

simple_animated_staggered 是一个Flutter插件,可以轻松为 ListViewGridViewColumnRow 的子项添加交错动画。该插件基于 flutter_staggered_animations 进行了改进和扩展。

安装

依赖

pubspec.yaml 文件中添加以下依赖:

dependencies:
  simple_annimated_staggered: ^0.0.3

导入

在代码文件中导入该包:

import 'package:simple_annimated_staggered/simple_annimated_staggered.dart';

基本用法

以下是为 ListView 子项应用交错动画的示例代码:

@override
Widget build(BuildContext context) {
  return Scaffold(
    body: AnimationLimiter(
      child: ListView.builder(
        itemCount: 100,
        itemBuilder: (BuildContext context, int index) {
          return AnimationConfiguration.staggeredList(
            position: index,
            duration: const Duration(milliseconds: 375),
            child: SlideAnimation(
              verticalOffset: 50.0,
              child: FadeInAnimation(
                child: YourListChild(),
              ),
            ),
          );
        },
      ),
    ),
  );
}

API 概览

该包包含三个主要类:

  • Animation
  • AnimationConfiguration
  • AnimationLimiter

动画

动画分为四种类型:

  • FadeInAnimation
  • SlideAnimation
  • ScaleAnimation
  • FlipAnimation

可以通过组合这些动画来创建更复杂的动画效果。例如,将 SlideAnimationFadeInAnimation 组合:

child: SlideAnimation(
  verticalOffset: 50.0,
  child: FadeInAnimation(
    child: YourListChild(),
  ),
)

AnimationConfiguration

AnimationConfiguration 是一个 InheritedWidget,用于共享其子项的动画设置(主要是持续时间和延迟)。

命名构造函数

根据不同的场景选择合适的构造函数:

  • AnimationConfiguration.synchronized:同时启动所有子项的动画。
  • AnimationConfiguration.staggeredList:按顺序启动每个子项的动画,以产生单轴交错动画。
  • AnimationConfiguration.staggeredGrid:按顺序启动每个子项的动画,以产生双轴交错动画。

如果不在 ListViewGridView 的上下文中,可以使用 AnimationConfiguration.toStaggeredList 静态方法为 RowColumn 的子项应用交错动画。

AnimationLimiter

在滚动视图中,只有当用户滚动并且子项出现在屏幕上时,才会构建子项的动画。这会导致在滚动过程中运行动画。如果不希望这种行为,可以使用 AnimationLimiter

AnimationLimiter 是一个 InheritedWidget,防止未在 AnimationLimiter 构建的第一帧中出现的子项进行动画。

快速示例

ListView 示例

@override
Widget build(BuildContext context) {
  return Scaffold(
    body: AnimationLimiter(
      child: ListView.builder(
        itemCount: 100,
        itemBuilder: (BuildContext context, int index) {
          return AnimationConfiguration.staggeredList(
            position: index,
            duration: const Duration(milliseconds: 375),
            child: SlideAnimation(
              verticalOffset: 50.0,
              child: FadeInAnimation(
                child: YourListChild(),
              ),
            ),
          );
        },
      ),
    ),
  );
}

GridView 示例

@override
Widget build(BuildContext context) {
  int columnCount = 3;

  return Scaffold(
    body: AnimationLimiter(
      child: GridView.count(
        crossAxisCount: columnCount,
        children: List.generate(
          100,
          (int index) {
            return AnimationConfiguration.staggeredGrid(
              position: index,
              duration: const Duration(milliseconds: 375),
              columnCount: columnCount,
              child: ScaleAnimation(
                child: FadeInAnimation(
                  child: YourListChild(),
                ),
              ),
            );
          },
        ),
      ),
    ),
  );
}

Column 示例

@override
Widget build(BuildContext context) {
  return Scaffold(
    body: SingleChildScrollView(
      child: AnimationLimiter(
        child: Column(
          children: AnimationConfiguration.toStaggeredList(
            duration: const Duration(milliseconds: 375),
            childAnimationBuilder: (widget) => SlideAnimation(
              horizontalOffset: 50.0,
              child: FadeInAnimation(
                child: widget,
              ),
            ),
            children: YourColumnChildren(),
          ),
        ),
      ),
    ),
  );
}

完整示例 Demo

以下是一个完整的示例应用程序,展示了如何使用 simple_animated_staggered 插件为 ListViewGridViewColumn 添加动画。

import 'package:flutter/material.dart';

void main() => runApp(const App());

class App extends StatelessWidget {
  const App({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      theme: ThemeData(
        brightness: Brightness.light,
        scaffoldBackgroundColor: const Color.fromRGBO(239, 238, 239, 1.0),
      ),
      home: const HomeScreen(),
    );
  }
}

class HomeScreen extends StatelessWidget {
  const HomeScreen({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: SizedBox(
        height: double.infinity,
        width: double.infinity,
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            ElevatedButton(
              child: const Text('List Card Test'),
              onPressed: () {
                Navigator.push(
                  context,
                  MaterialPageRoute(builder: (context) => const CardListScreen()),
                );
              },
            ),
            ElevatedButton(
              child: const Text('Grid Card Test'),
              onPressed: () {
                Navigator.push(
                  context,
                  MaterialPageRoute(builder: (context) => const CardGridScreen()),
                );
              },
            ),
            ElevatedButton(
              child: const Text('Column Card Test'),
              onPressed: () {
                Navigator.push(
                  context,
                  MaterialPageRoute(builder: (context) => const CardColumnScreen()),
                );
              },
            ),
          ],
        ),
      ),
    );
  }
}

class CardListScreen extends StatelessWidget {
  const CardListScreen({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('List View Animation')),
      body: AnimationLimiter(
        child: ListView.builder(
          itemCount: 100,
          itemBuilder: (BuildContext context, int index) {
            return AnimationConfiguration.staggeredList(
              position: index,
              duration: const Duration(milliseconds: 375),
              child: SlideAnimation(
                verticalOffset: 50.0,
                child: FadeInAnimation(
                  child: Container(
                    margin: const EdgeInsets.all(10),
                    height: 100,
                    color: Colors.blueAccent,
                    child: Center(child: Text('Item $index')),
                  ),
                ),
              ),
            );
          },
        ),
      ),
    );
  }
}

class CardGridScreen extends StatelessWidget {
  const CardGridScreen({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    int columnCount = 3;
    return Scaffold(
      appBar: AppBar(title: const Text('Grid View Animation')),
      body: AnimationLimiter(
        child: GridView.count(
          crossAxisCount: columnCount,
          children: List.generate(
            100,
            (int index) {
              return AnimationConfiguration.staggeredGrid(
                position: index,
                duration: const Duration(milliseconds: 375),
                columnCount: columnCount,
                child: ScaleAnimation(
                  child: FadeInAnimation(
                    child: Container(
                      margin: const EdgeInsets.all(10),
                      height: 100,
                      color: Colors.greenAccent,
                      child: Center(child: Text('Item $index')),
                    ),
                  ),
                ),
              );
            },
          ),
        ),
      ),
    );
  }
}

class CardColumnScreen extends StatelessWidget {
  const CardColumnScreen({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Column Animation')),
      body: SingleChildScrollView(
        child: AnimationLimiter(
          child: Column(
            children: AnimationConfiguration.toStaggeredList(
              duration: const Duration(milliseconds: 375),
              childAnimationBuilder: (widget) => SlideAnimation(
                horizontalOffset: 50.0,
                child: FadeInAnimation(
                  child: widget,
                ),
              ),
              children: List.generate(
                100,
                (int index) {
                  return Container(
                    margin: const EdgeInsets.all(10),
                    height: 100,
                    color: Colors.redAccent,
                    child: Center(child: Text('Item $index')),
                  );
                },
              ),
            ),
          ),
        ),
      ),
    );
  }
}

以上示例展示了如何在 ListViewGridViewColumn 中使用 simple_animated_staggered 插件来实现各种交错动画效果。通过组合不同的动画类型,您可以创建出丰富多样的动画效果。


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

1 回复

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


当然,以下是如何在Flutter中使用simple_animated_staggered插件来创建动画列表的一个示例代码。simple_animated_staggered插件可以让你轻松地创建具有交错动画效果的列表。

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

dependencies:
  flutter:
    sdk: flutter
  simple_animated_staggered: ^0.3.0  # 请检查最新版本号

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

以下是一个完整的示例代码,展示了如何使用SimpleAnimatedStaggeredList来创建一个带有交错动画的列表:

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

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatelessWidget {
  final List<String> items = List.generate(20, (index) => "Item $index");

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Simple Animated Staggered List'),
      ),
      body: Padding(
        padding: const EdgeInsets.all(8.0),
        child: SimpleAnimatedStaggeredList(
          itemCount: items.length,
          itemBuilder: (context, index) {
            return Container(
              decoration: BoxDecoration(
                border: Border.all(color: Colors.grey.withOpacity(0.5)),
                borderRadius: BorderRadius.circular(8),
              ),
              margin: EdgeInsets.symmetric(vertical: 8.0, horizontal: 4.0),
              padding: EdgeInsets.all(16.0),
              child: Text(
                items[index],
                style: TextStyle(fontSize: 18),
              ),
            );
          },
          staggeredConfig: StaggeredConfig.onlyScale(
            animationDuration: Duration(milliseconds: 300),
            crossAxisCount: 2,
            mainAxisSpacing: 8.0,
            crossAxisSpacing: 8.0,
          ),
        ),
      ),
    );
  }
}

代码说明:

  1. 依赖导入:首先导入flutter/material.dartsimple_animated_staggered/simple_animated_staggered.dart

  2. 创建主应用MyApp是一个无状态小部件,它定义了一个基本的Material应用,并设置了主题和主页。

  3. 主页MyHomePage是一个无状态小部件,它包含一个列表项数组items。在build方法中,它返回一个Scaffold,其中包含一个应用栏和一个填充了SimpleAnimatedStaggeredListPadding

  4. SimpleAnimatedStaggeredList

    • itemCount:指定列表中的项目数。
    • itemBuilder:定义每个列表项的构建方式。在这个例子中,每个列表项都是一个带有边框和圆角的容器,里面包含一个文本。
    • staggeredConfig:定义交错动画的配置。这里使用StaggeredConfig.onlyScale来仅应用缩放动画,并设置了动画持续时间、交叉轴上的项目数、主轴和交叉轴上的间距。

运行这个示例代码,你会看到一个带有交错缩放动画效果的列表。simple_animated_staggered插件允许你根据需要自定义动画效果,比如添加旋转、透明度变化等。你可以查阅其官方文档了解更多配置选项。

回到顶部