flutter3.0学习笔记

AnimatedCrossFade

Preview
  • AnimatedCrossFade

AnimatedCrossFade

在两个不同的子控件及其大小之间淡入淡出动画,因此AnimatedCrossFade需要设置2个子控件、动画时间和显示第几个子控件。

  • 构造函数
 const AnimatedCrossFade({
    super.key,
    required this.firstChild,//第一个子控件
    required this.secondChild,//第二个子控件
    this.firstCurve = Curves.linear,//第一个子控件动画曲线
    this.secondCurve = Curves.linear,//第二个子控件动画曲线
    this.sizeCurve = Curves.linear,//组件动画曲线
    this.alignment = Alignment.topCenter,//对齐位置
    required this.crossFadeState,//显示的孩子将淡入,而另一个将淡出
    required this.duration,//动画时间
    this.reverseDuration,//方向动画时间
    this.layoutBuilder = defaultLayoutBuilder,//解决过渡抖动问题
    this.excludeBottomFocus = true,
  })
  • layoutBuilder 当我们从一个状态转到另一个状态时,会有一个奇怪的跳跃,这时会用到layoutbuilderlayoutbuilder将返回一个Stack带有两个Positioned小部件的小部件。第一个 Positioned 小部件将获取bottomChild小部件,第二个 Positioned 小部件将获取topChild小部件。

例子:

import 'package:flutter/material.dart';

class AnimatedCrossFadePage extends StatefulWidget {
  const AnimatedCrossFadePage({Key? key}) : super(key: key);

  @override
  State<AnimatedCrossFadePage> createState() => _AnimatedCrossFadePageState();
}

class _AnimatedCrossFadePageState extends State<AnimatedCrossFadePage> {
  bool showPost = false;//渲染
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('AnimatedCrossFade'),),
      body: Center(
        child: AnimatedCrossFade(
          firstChild: GestureDetector(
            onTap: (){
              setState(() {
                showPost = true;
              });
            },
            child: Container(
              width: 300,
              height: 400,
              color: Colors.black,
              child: Column(
                mainAxisAlignment: MainAxisAlignment.center,
                children:  [
                  const Text('第一个widget',style: TextStyle(fontSize: 30,color: Colors.white),),
                  const SizedBox(height: 200,),
                  OutlinedButton(
                    onPressed: (){
                      setState(() {
                        showPost = true;
                      });
                    },
                    child: const Text('点击淡出'),
                  )
                ],
              ),
            ),
          ),
          secondChild: GestureDetector(
            onTap: (){
              setState(() {
                showPost = false;
              });
            },
            child: Container(
              width: 400,
              height: 500,
              color: Colors.blueGrey,
              child: Image.asset('images/liu.webp'),
            ),
          ),
          duration: const Duration(seconds: 1),
          crossFadeState: !showPost ? CrossFadeState.showFirst: CrossFadeState.showSecond,
          layoutBuilder: (topChild,topChildKey,bottomChild, bottomChildKey){
            return Stack(
            //必须添加Alignment.center和clipBehaviourClip.none,不然达不到预期效果 
              clipBehavior: Clip.none,
              alignment: Alignment.center,
              children: [
                Positioned(
                  key: bottomChildKey,
                  top: 0.0,
                  child: bottomChild,
                ),
                Positioned(
                  key: topChildKey,
                  child: topChild,
                ),
              ],
            );
          },
        ),
        
      ),
    );
  }
}

效果:

cor.gif