微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

首次加载时列中小部件的颤动浮动和淡入动画

如何解决首次加载时列中小部件的颤动浮动和淡入动画

我正在尝试创建动画屏幕,例如,当屏幕加载时,每个屏幕都会包含一个带有小部件的列。我想要做的是,当加载屏幕时,让列中的每个小部件按照它们出现的顺序从屏幕外(从底部)浮动。

我一直在寻找,但似乎找不到解决方案。我怎样才能做到这一点?

解决方法

我已经做了一些可能是你想要的。但是,为了使每个元素在最后一个元素之后为自己设置动画,而不是全部在一起,我必须使用 ListView.builder 来获取 index。如果您能找出元素的 Column,则可以使用 index 小部件。

代码如下:

主屏幕:

import 'package:flutter/material.dart';
import 'package:testing/fade_in_from_bottom.dart';

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

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

class HomePage extends StatelessWidget {
  final List<Widget> children = <Widget>[
    Container(
      height: 32.0,color: Colors.amber,Container(
      height: 32.0,color: Colors.black,color: Colors.purple,color: Colors.green,color: Colors.indigo,];

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Column(
        mainAxisAlignment: MainAxisAlignment.center,children: <Widget>[
          Expanded(
            child: ListView.builder(
              itemCount: children.length,itemBuilder: (BuildContext context,int index) {
                return FadeInFromBottom(
                  key: UniqueKey(),// this is very important
                  index: index,child: children[index],);
              },],);
  }
}

这是我制作的 FadeInFromBottom 小部件:

import 'package:flutter/material.dart';

class FadeInFromBottom extends StatefulWidget {
  @override
  _FadeInFromBottomState createState() => _FadeInFromBottomState();
  final Key key;
  final Duration animationDuration;
  final Duration offsetDuration;
  final Widget child;
  final int index;
  FadeInFromBottom({
    @required this.key,@required this.child,@required this.index,this.animationDuration = const Duration(milliseconds: 400),this.offsetDuration = const Duration(milliseconds: 800),}) : super(key: key); // this line is important
}

// How to add AutomaticKeepAliveClientMixin? Follow steps 1,2 and 3:

// 1. add AutomaticKeepAliveClientMixin to FadeInFromBottom widget State
class _FadeInFromBottomState extends State<FadeInFromBottom>
    with TickerProviderStateMixin,AutomaticKeepAliveClientMixin {
  bool get wantKeepAlive => true; // 2. add this line
  double progress = 0.0;

  Animation<double> animation;
  AnimationController controller;

  @override
  void initState() {
    super.initState();
    final Duration offsetDuration =
        widget.offsetDuration == null ? 0.0 : widget.offsetDuration;
    final int index = widget.index == null ? 0 : widget.index;
    
    // we await the future to create the animation delay
    Future.delayed(offsetDuration * index).then(
      (_) {
        controller = AnimationController(
            duration: widget.animationDuration,vsync: this);
        animation = Tween<double>(begin: 0.0,end: 1.0).animate(
          CurvedAnimation(
            parent: controller,curve: Curves.linear,)..addListener(() {
            setState(() => progress = animation.value);
          });

        controller.forward();
      },);
  }

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

  @override
  Widget build(BuildContext context) {
    super.build(context); // 3. add this line
    return Opacity(
      opacity: progress,child: Transform.translate(
        offset: Offset(
          0.0,(1.0 - progress) * 999.0,child: widget.child,);
  }
}

不要忘记添加 key: UniqueKey() 属性,如果没有它,动画会变得一团糟。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。