Flutter动画效果插件animated_widgets的使用

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

Flutter动画效果插件animated_widgets的使用

使用animated_widgets插件可以轻松地在你的Flutter应用中添加动画效果。该插件支持多种动画类型,包括位移、透明度、旋转、缩放、大小变化等。

安装

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

dependencies:
  animated_widgets: ^1.1.0

然后运行flutter pub get来安装该包。

使用示例

OpacityAnimatedWidget

OpacityAnimatedWidget可以用于控制一个子组件的透明度。例如,我们可以创建一个按钮来切换透明度动画的开启与关闭状态。

class _StatefulScreenState extends State<StatefulScreen> {
  bool _display = false;

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(),
      body: Column(
        crossAxisAlignment: CrossAxisAlignment.stretch,
        mainAxisAlignment: MainAxisAlignment.center,
        mainAxisSize: MainAxisSize.max,
        children: [
          // 使用OpacityAnimatedWidget包裹你的子组件
          OpacityAnimatedWidget.tween(
            opacityEnabled: 1, // 开始值为全透明
            opacityDisabled: 0, // 结束值为不透明
            enabled: _display, // 控制动画的开启与关闭
            child: Container(
              height: 200,
              width: 200,
              child: FlutterLogo(style: FlutterLogoStyle.stacked),
            ),
          ),
          RaisedButton(
            color: Colors.blue,
            child: Text(
              _display ? "隐藏logo" : "显示logo",
              style: TextStyle(color: Colors.white),
            ),
            onPressed: () {
              setState(() {
                _display = !_display;
              });
            },
          )
        ],
      ),
    );
  }
}

TranslationAnimatedWidget

TranslationAnimatedWidget可以用于控制一个子组件的位置变化。例如,我们可以创建一个按钮来触发位移动画。

class FirstScreenBloc extends Bloc {
  final _viewState = BehaviorSubject<FirstScreenViewState>.seeded(FirstScreenViewState());
  Observable<FirstScreenViewState> get viewState => _viewState;

  void onClicked() {
    _viewState.add(FirstScreenViewState(buttonVisible: true));
  }

  void onDismissClicked() {
    _viewState.add(FirstScreenViewState(buttonVisible: false));
  }

  [@override](/user/override)
  void dispose() {
    _viewState.close();
  }
}

class FirstScreenViewState {
  final bool buttonVisible;

  const FirstScreenViewState({this.buttonVisible = false});
}

class FirstScreenView extends StatelessWidget {
  [@override](/user/override)
  Widget build(BuildContext context) {
    final bloc = BlocProvider.of<FirstScreenBloc>(context);

    return StreamBuilder<FirstScreenViewState>(
      stream: bloc.viewState,
      builder: (context, snapshot) {
        final viewState = snapshot.data;

        return Stack(
          fit: StackFit.expand,
          children: [
            _buildInputButton(onClicked: () {
              bloc.onClicked();
            }),
            Positioned(
              bottom: 20,
              left: 20,
              right: 20,
              child: TranslationAnimatedWidget(
                enabled: viewState.buttonVisible,
                curve: Curves.easeIn,
                duration: Duration(seconds: 1),
                values: [
                  Offset(0, 200),
                  Offset(0, -50),
                  Offset(0, 0),
                ],
                child: RaisedButton(
                  onPressed: () {
                    bloc.onDismissClicked();
                  },
                  child: Text("取消"),
                ),
              ),
            ),
          ],
        );
      },
    );
  }
}

RotationAnimatedWidget

RotationAnimatedWidget可以用于控制一个子组件的旋转变化。例如,我们可以创建一个按钮来触发旋转动画。

class RotationScreen extends StatelessWidget {
  [@override](/user/override)
  Widget build(BuildContext context) {
    return Center(
      child: RotationAnimatedWidget.tween(
        enabled: true,
        rotationDisabled: Rotation.deg(),
        rotationEnabled: Rotation.deg(z: 90, x: 80),
        child: Container(
          height: 200,
          width: 200,
          child: FlutterLogo(style: FlutterLogoStyle.stacked),
        ),
      ),
    );
  }
}

ScaleAnimatedWidget

ScaleAnimatedWidget可以用于控制一个子组件的缩放变化。例如,我们可以创建一个按钮来触发缩放动画。

class ScaleScreen extends StatelessWidget {
  [@override](/user/override)
  Widget build(BuildContext context) {
    return Center(
      child: ScaleAnimatedWidget.tween(
        enabled: true,
        duration: Duration(milliseconds: 600),
        scaleDisabled: 0.5,
        scaleEnabled: 1,
        child: Container(
          height: 200,
          width: 200,
          child: FlutterLogo(style: FlutterLogoStyle.stacked),
        ),
      ),
    );
  }
}

SizeAnimatedWidget

SizeAnimatedWidget可以用于控制一个子组件的尺寸变化。例如,我们可以创建一个按钮来触发尺寸动画。

class SizeScreen extends StatelessWidget {
  [@override](/user/override)
  Widget build(BuildContext context) {
    return Center(
      child: SizeAnimatedWidget(
        enabled: true,
        duration: Duration(milliseconds: 1500),
        values: [Size(100, 100), Size(100, 150), Size(200, 150), Size(200, 200)],
        curve: Curves.linear,
        child: Container(
          decoration: BoxDecoration(border: Border.all(color: Colors.blue)),
          child: FlutterLogo(style: FlutterLogoStyle.stacked),
        ),
      ),
    );
  }
}

ShakeAnimatedWidget

ShakeAnimatedWidget可以用于模拟一个子组件的震动效果。例如,我们可以创建一个按钮来触发震动动画。

class ShakeScreen extends StatelessWidget {
  [@override](/user/override)
  Widget build(BuildContext context) {
    return Center(
      child: ShakeAnimatedWidget(
        enabled: true,
        duration: Duration(milliseconds: 1500),
        shakeAngle: Rotation.deg(z: 40),
        curve: Curves.linear,
        child: FlutterLogo(style: FlutterLogoStyle.stacked),
      ),
    );
  }
}

CustomAnimatedWidget

CustomAnimatedWidget可以用于创建自定义的动画效果。例如,我们可以创建一个按钮来触发自定义动画。

class CustomScreen extends StatelessWidget {
  [@override](/user/override)
  Widget build(BuildContext context) {
    return Center(
      child: CustomAnimatedWidget(
        enabled: true,
        duration: Duration(seconds: 3),
        curve: Curves.easeOut,
        builder: (context, percent) {
          final int displayedDate = (2018 * percent).floor();
          return Text(
            "当前年份 : $displayedDate",
            style: TextStyle(color: Colors.blue),
          );
        },
      ),
    );
  }
}

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

1 回复

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


当然,animated_widgets 是一个流行的 Flutter 插件,它提供了一系列预构建的动画组件,让开发者能够轻松地在应用中实现各种动画效果。下面我将通过代码示例展示如何使用 animated_widgets 插件来实现一些常见的动画效果。

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

dependencies:
  flutter:
    sdk: flutter
  animated_widgets: ^0.6.1  # 请根据需要检查最新版本号

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

示例1:使用 AnimatedCrossFade

AnimatedCrossFade 可以在两个子组件之间进行平滑过渡。

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

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('AnimatedCrossFade Example'),
        ),
        body: Center(
          child: AnimatedCrossFade(
            firstChild: Text('First Widget'),
            secondChild: Text('Second Widget'),
            crossFadeState: _isFirstChildVisible(DateTime.now().second % 2 == 0),
            duration: Duration(seconds: 1),
          ),
        ),
        floatingActionButton: FloatingActionButton(
          onPressed: () {},
          child: Icon(Icons.refresh),
        ), // 这个按钮仅用于展示,不连接任何逻辑
      ),
    );
  }

  CrossFadeState _isFirstChildVisible(bool isVisible) {
    return isVisible ? CrossFadeState.showFirst : CrossFadeState.showSecond;
  }
}

示例2:使用 AnimatedSwitcher with TransitionBuilder

虽然 AnimatedSwitcher 不是 animated_widgets 插件的一部分,但结合 TransitionBuilder 可以实现更复杂的动画效果。这里为了完整性,我还是展示一下如何使用 AnimatedSwitcher

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('AnimatedSwitcher Example'),
        ),
        body: Center(
          child: AnimatedSwitcher(
            duration: Duration(seconds: 1),
            child: _getCurrentChild(),
            transitionBuilder: (Widget child, Animation<double> animation) {
              return ScaleTransition(
                scale: animation,
                child: child,
              );
            },
          ),
        ),
        floatingActionButton: FloatingActionButton(
          onPressed: () {
            setState(() {}); // 触发重建以切换子组件
          },
          child: Icon(Icons.add),
        ),
      ),
    );
  }

  Widget _getCurrentChild() {
    // 简单示例:每次点击按钮时切换两个文本组件
    return DateTime.now().second % 2 == 0
        ? Text('First Widget')
        : Text('Second Widget');
  }
}

注意:虽然 AnimatedSwitcher 不是 animated_widgets 插件的一部分,但它是 Flutter 框架自带的,展示了如何结合动画和状态管理来实现组件切换。

示例3:使用 AnimatedOpacity (虽然不是 animated_widgets 但常用)

AnimatedOpacity 可以用来平滑地改变子组件的不透明度。

import 'package:flutter/material.dart';

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

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> with SingleTickerProviderStateMixin {
  double _opacity = 1.0;

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('AnimatedOpacity Example'),
        ),
        body: Center(
          child: AnimatedOpacity(
            opacity: _opacity,
            duration: Duration(seconds: 1),
            child: Text('This text will fade in and out'),
          ),
        ),
        floatingActionButton: FloatingActionButton(
          onPressed: () {
            setState(() {
              _opacity = _opacity == 1.0 ? 0.0 : 1.0;
            });
          },
          child: Icon(
            _opacity == 1.0 ? Icons.visibility : Icons.visibility_off,
          ),
        ),
      ),
    );
  }
}

这些示例展示了如何使用 animated_widgets 插件以及 Flutter 自带的动画组件来实现不同的动画效果。根据你的具体需求,你可以进一步定制和扩展这些动画。

回到顶部