我的应用程序中有一个页面,如果打开该页面,会显示3个文本从屏幕左侧飞入,一个接一个,持续时间为1秒,位于页面中心。我如何实现此动画,必须使用哪个flutter包?
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!')) ], ))), ); } }
1条答案
按热度按时间zujrkrfu1#