Flutter | AnimatedCrossFade - 交叉淡入 Widget

主要来讲解 AnimatedCrossFade 该组件使用的方式和大致可以使用的场景。

先来了解一下 AnimatedCrossFade

1. 首先看一下官方介绍

A widget that cross-fades between two given children and animates itself between their sizes.

在两个子 Widget 之间交叉淡入并在其大小之间设置动画的小部件。

其中「交叉淡入」其实是电影中的术语,意思就是由一个要素进入另一个要素。

也就是「由一个 Widget 进入另一个 Widget」

2. 再来看一下构造函数

const AnimatedCrossFade({
  Key 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,
}) : assert(firstChild != null),
assert(secondChild != null),
assert(firstCurve != null),
assert(secondCurve != null),
assert(sizeCurve != null),
assert(alignment != null),
assert(crossFadeState != null),
assert(duration != null),
assert(layoutBuilder != null),
super(key: key);

可以看到必要的参数有四个:

1.

firstChild:第一个 childWidget,也就是直接展示的那个

2.

secondChild:第二个 childWidget,切换时显示的

3.crossFadeState:final CrossFadeState crossFadeState,是一个枚举:

um CrossFadeState {
  /// Show the first child ([AnimatedCrossFade.firstChild]) and hide the second
  /// ([AnimatedCrossFade.secondChild]]).
  showFirst,

  /// Show the second child ([AnimatedCrossFade.secondChild]) and hide the first
  /// ([AnimatedCrossFade.firstChild]).
  showSecond,
}

4.duration:不多说,动画切换的时间

有了这四个参数,我们就能用它了。

跟着官方 Demo 来写一下

看一下代码:

AnimatedCrossFade(
  duration: const Duration(seconds: 3),
  firstChild: const FlutterLogo(style: FlutterLogoStyle.horizontal, size: 100.0),
  secondChild: const FlutterLogo(style: FlutterLogoStyle.stacked, size: 100.0),
  crossFadeState: _first ? CrossFadeState.showFirst : CrossFadeState.showSecond,
)

先看效果:

这不就跟 AnimatedSwitcher 一样吗?

这么看起来确实其实没什么屌的,官方的demo只是给你一个简单的使用方法而已。

我们可以从刚才的官方介绍里找到一点不一样的地方:「并在其大小之间设置动画」

那我们给他们套上颜色,并且改一下大小来看看:

有内味了是不,可是这切换回来的时候怎么有点鬼畜的感觉?不要着急。

稍微深入一下源码

为什么会有鬼畜的效果?遇事不决看源码,去年在写文章的时候说过,Flutter 的源码里有特别多的注释和 demo。那就先来看一下他的注释:

/// The animation is controlled through the [crossFadeState] parameter.
/// [firstCurve] and [secondCurve] represent the opacity curves of the two
/// children. The [firstCurve] is inverted, i.e. it fades out when providing a
/// growing curve like [Curves.linear]. The [sizeCurve] is the curve used to
/// animate between the size of the fading-out child and the size of the
/// fading-in child.
///
/// This widget is intended to be used to fade a pair of widgets with the same
/// width. In the case where the two children have different heights, the
/// animation crops overflowing children during the animation by aligning their
/// top edge, which means that the bottom will be clipped.
///
/// The animation is automatically triggered when an existing
/// [AnimatedCrossFade] is rebuilt with a different value for the
/// [crossFadeState] property.


动画是通过[crossFadeState]参数控制的。[firstCurve]和[secondCurve]表示两个孩子的不透明度曲线。[firstCurve]是倒置的,即当提供诸如[Curves.linear]之类的增长曲线时,它会淡出。[sizeCurve]是用于在淡出子项的大小和淡入子项的大小之间进行动画处理的曲线。

此小部件用于淡化一对具有相同宽度的小部件。如果两个孩子的高度不同,则动画会在动画过程中通过对齐它们的顶部边缘来裁剪溢出的child,这意味着将裁剪底部。

当以不同的值重建现有的[AnimatedCrossFade]时,动画会自动触发。

画重点:如果两个孩子的高度不同,则动画会在动画过程中通过对齐它们的顶部边缘来裁剪溢出的child,这意味着将裁剪底部。

对齐顶部边缘和裁剪底部,那我们还是先来看一下 AnimatedCrossFade 是如何做到 在大小之间做动画的

具体重点代码如下:

@override
Widget build(BuildContext context) {
  // ...
  // 去掉于此无关代码
  return ClipRect(
    child: AnimatedSize(
      alignment: widget.alignment,
      duration: widget.duration,
      reverseDuration: widget.reverseDuration,
      curve: widget.sizeCurve,
      vsync: this,
      child: widget.layoutBuilder(topChild, topKey, bottomChild, bottomKey),
    ),
  );
}

// -----------------------------------------
//           defaultLayoutBuilder
// -----------------------------------------
static Widget defaultLayoutBuilder(Widget topChild, Key topChildKey, Widget bottomChild, Key bottomChildKey) {
  return Stack(
    overflow: Overflow.visible,
    children: <Widget>[
      Positioned(
        key: bottomChildKey,
        left: 0.0,
        top: 0.0,
        right: 0.0,
        child: bottomChild,
      ),
      Positioned(
        key: topChildKey,
        child: topChild,
      ),
    ],
  );
}

如果我们没有给 layoutBuilder 这个参数的时候,默认是有一个 defaultLayoutBuilder 的,这个里面就有前面所看到的那句话 对齐它们的顶部边缘来裁剪,所以当我们从第二个 child 回到第一个 child 的时候,就会发生宽度突然变化,解决办法也很简单:

layoutBuilder: (topChild, topChildKey, bottomChild, bottomChildKey) {
  return Stack(
    overflow: Overflow.visible,
    alignment: Alignment.center,
    children: <Widget>[
      Positioned(
        key: topChildKey,
        child: topChild,
      ),
      Positioned(
        key: bottomChildKey,
        top:0,
        child: bottomChild,
      ),
    ],
  );
}

把第二个的 leftright 去掉,并且加上 alignment: Alignment.center,这样就完成了,再来看一下效果:

思考题

鉴于 AnimatedCrossFade 的这个特性,我做了一个小 Demo,效果如下:

这玩意能玩出什么效果?

使用 Flutter 加速应用开发

发布于:6天以前  |  40次阅读  |  详细内容 »

深入分析 Flutter 渲染性能

发布于:7天以前  |  43次阅读  |  详细内容 »

深入分析 Flutter 渲染性能

发布于:12天以前  |  56次阅读  |  详细内容 »

Flutter 不是真正的跨平台框架

发布于:23天以前  |  159次阅读  |  详细内容 »

Flutter 2 来了!

发布于:28天以前  |  165次阅读  |  详细内容 »

Flutter Worker —— 闲鱼这样实现“逻辑跨平台”

发布于:1月以前  |  142次阅读  |  详细内容 »

针对 Web,移动端和桌面端构建的下一代 Flutter

发布于:1月以前  |  127次阅读  |  详细内容 »

使用 flutter_driver 进行集成测试

单元测试可以确保应用的各个部分正常工作,但如何确保整个应用正常工作呢?这就需要用到集成测试了。

发布于:5月以前  |  596次阅读  |  详细内容 »

详解:Flutter内存泄漏解决方案

众所周知,内存的高低是评判一款app的性能优劣的重要的指标之一。如何更简单的帮助开发者分析、暴露且解决内存泄漏问题,几乎是每一个平台或框架、开发者亟需的一个的"标配"的feature。但是对于flutter社区,缺少一款用得顺手的内存泄漏工具。 对于使用flutter而言,因使用dart语言,通过形成渲染树提交到c++的skia进行渲染,从dart层到c++层拥有很长的渲染链路,使用者必须对整个渲染链路有通盘深刻的理解,才能深刻此时此刻的内存使用情况。本文提出一种基于渲染树个数的方式寻找内存泄漏的解决方案。

发布于:5月以前  |  667次阅读  |  详细内容 »

开始使用 Flutter 构建 Windows 桌面应用吧!

我们的使命是为开发者提供一个开源的高效框架,帮助他们在任何平台上构建美观的原生应用。截至目前,我们已经为 Android 和 iOS 带来了生产级别的支持,发布了 8 个稳定版本,仅在 Google Play 商店中就有超过 10 万款应用使用 Flutter。我们在继续努力,将支持范围扩展至 web、macOS 和 Linux 等其他平台。如今,Flutter 的另一个目标,即支持 Windows 的 Flutter Alpha 版本已经发布。

发布于:5月以前  |  702次阅读  |  详细内容 »

如何有效定位Flutter内存问题?

内存水位升高导致的稳定性问题严重影响app用户体验,所以开发者们非常关注Flutter的内存表现。随着Flutter业务越来越多,闲鱼也面临着oom导致的crash率提升的问题,下面我们结合项目中实际遇到的内存问题和解决思路跟大家分享下flutter内存优化的经验。

发布于:6月以前  |  600次阅读  |  详细内容 »

推荐5个Flutter重磅开源项目!

大家好,我是hub哥,近年来,随着移动智能设备的快速普及,移动多端统一开发框架已成为一个热门话题。这里为大家整理了5个Flutter优质的开源项目,希望对大家有帮助

发布于:8月以前  |  1462次阅读  |  详细内容 »

Flutter在PLUS业务中的探索和实践

2016年京东为向核心客户提供更优质的购物体验,特别推出京东PLUS会员,旨在全方位提升和丰富用户网购体验,目前京东PLUS会员已成为电商行业付费人数最多的会员体系。作为PLUS的前端开发,我们思考最多的就是如何让页面更快更好的呈现在用户面前,如何用技术为用户提供最好的购物体验。

发布于:9月以前  |  1036次阅读  |  详细内容 »

京东技术中台Flutter实践之路(二)

发布于:9月以前  |  1316次阅读  |  详细内容 »

首发 | 闲鱼公开多年 Flutter 实践经验

Flutter从诞生到现在,已经成为了跨端开发的领跑者。闲鱼应用在flutter能够以模块形式存在前,进行了很长时间的混合app架构的探索,对原生工程进行较多改动,在官方推出flutter模块模式后,我们进行了大量调研,最终推出了一套开箱即用的混合工程脚手架flutter-boot,帮助大家快速搭建混合工程。

发布于:9月以前  |  1063次阅读  |  详细内容 »

打破重重阻碍,Flutter 和 Web 生态如何对接?

Flutter 设计之初是不考虑 Web 生态的,原因很简单:两种技术设计理念不同,强行融合很可能让彼此都丧失了优势。但是业界又有很多团队在做这种尝试,说明需求是存在的。今天,阿里无线开发专家门柳就来手把手教如何实现 Flutter 和 Web 生态的对接?

发布于:9月以前  |  1040次阅读  |  详细内容 »

"零"学习成本:使用 Web 标准开发动态化 Flutter 应用

Kraken 是由淘系技术部前端架构团队开发的一个基于 Flutter 的动态化框架,本文将带大家了解和认识 Kraken,分享 Kraken 的一些设计思想以及 Flutter 和 Web 技术对接的实践。

发布于:9月以前  |  950次阅读  |  详细内容 »

一文看完阿里巴巴 AliFlutter 客户端研发体系

Flutter 是开源的 UI 工具包,其能够帮助开发者通过一套代码库高效构建多平台精美应用,支持移动、Web、桌面和嵌入式平台。Flutter 组件采用现代响应式框架构建,中心思想是用组件 (widget) 构建 UI。淘宝终端技术部无线技术专家王康从 Flutter 的原理出发,介绍了 Flutter 的原理、业内现状,以及阿里巴巴在 Flutter 上所做的深度实践和探索。

发布于:9月以前  |  1085次阅读  |  详细内容 »

美团外卖Flutter动态化实践

动态化是 Flutter 无法避开的话题。本文从 Flutter 的特点讲起, 阐述了美团外卖团队在整个 Flutter 动态化上探索的心路历程,还有设计理念、核心原理以及业务应用的经验。本文的视角也不局限于框架本身,更多思考了在解决问题的过程中技术团队需要做的事情,希望能对大家有所启发和帮助。

发布于:9月以前  |  1058次阅读  |  详细内容 »

VS Code 成主宰、Vue备受热捧、Flutter成新贵!2020 前端开发趋势指南

前端在生产和开发中占据着越来越重要的地位,PC 端、手机端、桌面端、智能手表端等等设备都离不开前端的身影。本文将围绕框架、编程语言、工具、React、Vue 等方面,全面回顾 2019 年前端与 Web 开发的大事。

发布于:9月以前  |  1223次阅读  |  详细内容 »

最多阅读

Flutter的手势GestureDetector分析详解 1年以前  |  4072次阅读
Flutter插件详解及其发布插件 1年以前  |  3612次阅读
在Flutter中添加资源和图片 2年以前  |  3422次阅读
发布Flutter开发的iOS程序 2年以前  |  2675次阅读
Flutter 状态管理指南之 Provider 1年以前  |  2390次阅读
在Flutter中发起HTTP网络请求 2年以前  |  2330次阅读
Flutter for Web详细介绍 1年以前  |  2284次阅读
使用Inspector检查用户界面 2年以前  |  2267次阅读
Flutter Widget框架概述 2年以前  |  2123次阅读
JSON和序列化 2年以前  |  1946次阅读
Flutter框架概览 2年以前  |  1940次阅读
为Flutter应用程序添加交互 2年以前  |  1925次阅读
Flutter路由详解 1年以前  |  1902次阅读
使用自定义字体 2年以前  |  1814次阅读
处理文本输入 2年以前  |  1794次阅读
编写国际化Flutter App 2年以前  |  1744次阅读
使用包来开发Flutter应用 2年以前  |  1719次阅读
发布Flutter开发的Android程序 2年以前  |  1704次阅读