dart 如何在Flutter中制作“文字在屏幕上飞舞”动画

huus2vyu  于 2023-01-15  发布在  Flutter
关注(0)|答案(1)|浏览(95)

我的应用程序中有一个页面,如果打开该页面,会显示3个文本从屏幕左侧飞入,一个接一个,持续时间为1秒,位于页面中心。我如何实现此动画,必须使用哪个flutter包?

zujrkrfu

zujrkrfu1#

  • 我做的最基本的动画组件,希望对大家有用
import 'dart:math';

import 'package:flutter/material.dart';

enum AnimationType {
  ROTATION,
  OFFSET,
}

enum OffsetType {
  UP,
  DOWN,
  LEFT,
  RIGHT,
}

typedef AnimationSwich = bool Function();

class BaseAnimationWidget extends StatefulWidget {
  const BaseAnimationWidget(
      {Key? key,
      required this.type,
      required this.body,
      this.animationSwich,
      this.rotationValue,
      this.offset,
      this.duration,
      this.offsetType})
      : assert(type == AnimationType.ROTATION
            ? rotationValue != null
            : type == AnimationType.OFFSET
                ? offset != null && offsetType != null
                : true),
        super(key: key);
  final AnimationSwich? animationSwich;
  final Widget body;
  final Offset? offset;
  final double? rotationValue;
  final AnimationType type;
  final Duration? duration;
  final OffsetType? offsetType;
  @override
  State<BaseAnimationWidget> createState() => _BaseAnimationWidgetState();
}

class _BaseAnimationWidgetState extends State<BaseAnimationWidget>
    with SingleTickerProviderStateMixin {
  late AnimationController _animationController;
  @override
  void initState() {
    super.initState();
    _animationController = AnimationController(
        duration: widget.duration ?? Duration(milliseconds: 300), vsync: this);
  }

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

  Offset get _offset => widget.offsetType == OffsetType.UP ||
          widget.offsetType == OffsetType.DOWN
      ? Offset(
          widget.offset!.dx, widget.offset!.dy * _animationController.value)
      : Offset(
          widget.offset!.dx * _animationController.value, widget.offset!.dy);
  @override
  Widget build(BuildContext context) {
    if (widget.animationSwich == null) {
      DoNothingAction();
    } else if (mounted && widget.animationSwich!()) {
      _animationController.forward();
    } else if (mounted && !widget.animationSwich!()) {
      _animationController.reverse();
    }
    return AnimatedBuilder(
        animation: _animationController,
        builder: (context, _) {
          return widget.type == AnimationType.ROTATION
              ? Transform.rotate(
                  angle: widget.rotationValue! * _animationController.value,
                  child: widget.body)
              : Transform.translate(
                  offset: _offset,
                  child: widget.body,
                );
        });
  }
}

class MyWidget extends StatefulWidget {
  const MyWidget({super.key});

  @override
  State<MyWidget> createState() => _MyWidgetState();
}

class _MyWidgetState extends State<MyWidget> {
  var _animationSwich = true;

  @override
  Widget build(BuildContext context) {
    var width = MediaQuery.of(context).size.width;
    var height = MediaQuery.of(context).size.height;
    return Scaffold(
      body: SafeArea(
          child: Center(
              child: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        crossAxisAlignment: CrossAxisAlignment.center,
        children: [
          // Left
          BaseAnimationWidget(
            type: AnimationType.OFFSET,
            duration: Duration(seconds: 1),
            body: Text('Test'),
            offset: Offset(-width, 0),
            offsetType: OffsetType.LEFT,
            animationSwich: () => _animationSwich,
          ),
          // Right
          BaseAnimationWidget(
            type: AnimationType.OFFSET,
            duration: Duration(seconds: 1),
            body: Text('Test'),
            offset: Offset(width, 0),
            offsetType: OffsetType.RIGHT,
            animationSwich: () => _animationSwich,
          ),
          // Up
          BaseAnimationWidget(
            type: AnimationType.OFFSET,
            duration: Duration(seconds: 1),
            body: Text('Test'),
            offset: Offset(0, -height),
            offsetType: OffsetType.UP,
            animationSwich: () => _animationSwich,
          ),
          // Down
          BaseAnimationWidget(
            type: AnimationType.OFFSET,
            duration: Duration(seconds: 1),
            body: Text('Test'),
            offset: Offset(0, height),
            offsetType: OffsetType.DOWN,
            animationSwich: () => _animationSwich,
          ),
          // Rotation
          BaseAnimationWidget(
            type: AnimationType.ROTATION,
            duration: Duration(seconds: 1),
            body: Text('Test'),
            offset: Offset(-width, 0),
            offsetType: OffsetType.LEFT,
            rotationValue: pi,
            animationSwich: () => _animationSwich,
          ),

          TextButton(
              onPressed: () {
                _animationSwich = !_animationSwich;
                setState(() {});
              },
              child: Text('Action!'))
        ],
      ))),
    );
  }
}

相关问题