当前位置: 首页 > article >正文

Flutter 共性元素动画

在 Flutter 中,共性元素动画(Shared Element Transitions)用于在页面导航或组件切换时创建视觉上更流畅和连贯的动画效果。这种动画可以使用户感受到两个界面之间的“物理联系”,比如图片从缩略图到全屏的扩大效果。

前置知识点整理

Navigator

在 Flutter 中,`Navigator` 是一个用于管理应用页面的堆栈控件。通过 `Navigator`,您可以在应用中实现页面导航。`MaterialPageRoute` 是 Flutter 提供的一种常用的页面路由,它遵循 Material Design 的动画和过渡规范。

代码示例

Navigator.of(context).push(MaterialPageRoute(
    builder: (context) {
      return const Page();
    },
    fullscreenDialog: true
));

代码解析

`Navigator.of(context)`
  • `Navigator.of(context)` 获取与指定 `BuildContext` 关联的 `Navigator` 实例。`Navigator` 是一个用于管理应用页面导航的控件。
  • `context` 是当前小部件树中的上下文,通常在小部件的 `build` 方法中可以直接获取。
`push` 方法:

`push` 方法用于将新的路由(页面)推入导航堆栈的顶部。这会导致新页面显示在当前页面之上。

`MaterialPageRoute`:
  • MaterialPageRoute` 是一种实现 `PageRoute` 的类,用于在 Material Design 样式的应用中创建路由。
  • 它提供了标准的页面切换动画和过渡效果。
`builder` 参数:
  • `builder` 是一个回调函数,接收一个 `BuildContext` 参数,并返回一个要显示的新页面的小部件。
  • 在这个例子中,`builder` 返回一个 `Page` 实例。`const` 修饰符表示 `Page` 是不可变的,并且是编译时常量。
`fullscreenDialog` 参数:
  • `fullscreenDialog: true` 指定新页面是否应该以全屏对话框的形式出现。
  • 当 `fullscreenDialog` 设置为 `true` 时,新页面通常会从屏幕底部滑入,并带有关闭按钮(通常是一个“关闭”图标),这与典型的页面过渡动画有所不同,通常用于需要用户特别注意的内容页面。

使用场景

  • 标准页面导航: 使用 `MaterialPageRoute` 是创建标准 Material 设计风格页面的常用方法。它自动处理页面切换的动画和过渡效果。
  • 全屏对话框: 设置 `fullscreenDialog` 为 `true` 可以用于显示用户需要特别注意的内容,比如设置页面、表单页面等。它通常用于在移动应用中模拟对话框或模态视图。

注意事项

  • 航堆栈: 每次调用 `push` 方法时,新页面都会被添加到导航堆栈的顶部。当用户按下返回按钮或调用 `Navigator.pop(context)` 时,堆栈顶部的页面会被移除。
  • 上下文的使用: 确保 `context` 是当前页面的上下文,并且在适当的位置(如 `build` 方法中)使用它,以便正确获取 `Navigator` 实例。

这段代码展示了如何在 Flutter 应用中使用 `Navigator` 和 `MaterialPageRoute` 进行页面导航,并通过 `fullscreenDialog` 参数实现全屏对话框效果。

InkWell

`InkWell` 是 Flutter 中用于实现“水波纹”点击效果的一个小部件。当用户在支持 `Material` 设计的应用中点击某个组件时,`InkWell` 可以提供一个视觉反馈。这种点击效果通常用于提升用户体验,使交互更加直观。

`InkWell` 的主要属性

  • `child`:`InkWell` 的子小部件。通常是您希望作为点击目标的部件,比如一个文本、图标或者容器。
  • `onTap`:点击时触发的回调函数。当用户点击 `InkWell` 时,`onTap` 中的代码将被执行。
  • `onDoubleTap`:双击时触发的回调函数。
  • `onLongPress`:长按时触发的回调函数。
  • `onTapDown`:手指按下时触发的回调函数。
  • `onTapCancel`:点击被取消时触发的回调函数。
  • `borderRadius`:边界的圆角半径。在具有圆角的组件上使用时很有用。
  • `splashColor`:点击时水波纹的颜色。
  • `highlightColor`:点击时的高亮颜色。
  • `hoverColor`:悬停时的颜色(通常在桌面应用中使用)。

使用场景

  • 按钮:用作自定义按钮的点击效果。
  • 列表项:在列表中为每个项目添加点击反馈。
  • 卡片:为图片或卡片提供点击反馈。
  • 图标:为图标添加点击效果。

`InkWell` 是一个简单而强大的工具,用于实现点击反馈效果,使得 Flutter 应用的交互更加自然和直观。

Image.asset

`Image.asset` 是 Flutter 中用于加载和显示本地资源图片的一个构造方法。它是 `Image` 小部件的一种常用方式,用于从应用的资产中加载图片。

`Image.asset` 的主要属性

  • `String name`:图片资源的路径,相对于 `pubspec.yaml` 中定义的资产路径。
  • `Key key`:小部件的唯一标识符,用于优化 Flutter 的小部件树。
  • `double scale`:图片的比例因子,如果没有指定,Flutter 会根据设备的分辨率自动计算。
  • `ImageFrameBuilder frameBuilder`:用于构建每一帧的自定义小部件。
  • `ImageLoadingBuilder loadingBuilder`:用于在图片加载时显示自定义的加载指示器。
  • `BoxFit fit`:规定图片的缩放和剪裁方式。例如:`BoxFit.cover`、`BoxFit.contain` 等。
  • `AlignmentGeometry alignment`:控制图片的对齐方式,默认是 `Alignment.center`。
  • `ImageRepeat repeat`:控制图片的重复方式,例如:`ImageRepeat.repeat` 或 `ImageRepeat.noRepeat`。
  • `bool matchTextDirection`:是否根据文本方向自动镜像图像。
  • `bool gaplessPlayback`:图像在更新过程中是否保持显示。

使用步骤

在 `pubspec.yaml` 中声明资产:
  • 在 Flutter 项目中使用本地图片前,必须在 `pubspec.yaml` 文件中声明图片资产。
flutter:
  assets:
    - assets/images/my_image.png
组织项目目录:
  • 通常将图片存放在 `assets/images/` 目录中或其他自定义目录。
使用 `Image.asset` 加载图片。

使用场景

  • 应用图标:在应用的不同部分显示标识性图像。
  • 背景图像:作为其他 UI 元素的背景。
  • 产品展示:显示本地存储的产品图像。
  • 图形资产:例如图标、插图等静态资源。

通过 `Image.asset`,您可以方便地在 Flutter 应用中加载和显示本地图片资源。确保在 `pubspec.yaml` 中正确声明资产路径,并适当地组织项目目录,以便更好地管理图片资源。

Hero

Flutter 提供了一个简单的方式来实现共性元素动画,那就是使用 `Hero` 小部件。`Hero` 小部件可以在两个路由(页面)之间创建共享元素动画。

基本步骤

1.包装共享元素:在两个页面中,将共享的元素用 `Hero` 小部件包装。

2.指定相同的 tag:确保在两个 `Hero` 小部件上使用相同的 `tag` 标识。

3.导航:在导航到新的页面时,Flutter 自动处理共享元素的动画。

代码示例

import 'package:flutter/material.dart';

class MyHonorDemoPage extends StatelessWidget {
  const MyHonorDemoPage({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text("MyHonorDemoPage"),
      ),
      body: Center(
        child: InkWell(
          onTap: () {
            Navigator.of(context).push(MaterialPageRoute(
                builder: (context) {
                  return const MyHonorPage();
                },
                fullscreenDialog: true));
          },

          child: Hero(
            tag: "image",
            child: Image.asset(
               "static/my_icon.png",
              fit: BoxFit.cover,
              width: 100,
              height: 100,
            ),
          ),
        ),
      ),
    );
  }
}

class MyHonorPage extends StatelessWidget {
  const MyHonorPage({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.transparent,
      body: InkWell(
        onTap: () {
          Navigator.of(context).pop();
        },
        child: Container(
          alignment: Alignment.center,
          child: Hero(
            tag: "image",
            child: Image.asset(
              "static/my_icon.png",
              fit: BoxFit.cover,
              width: MediaQuery.sizeOf(context).width,
              height: MediaQuery.sizeOf(context).width,
            ),
          ),
        ),
      ),
    );
  }
}

注意事项

1.Tag 唯一性:确保每对共享元素的 `tag` 是唯一的,以避免动画错误。

2.动画时间:可以通过 `PageRoute` 自定义动画时间和曲线。


http://www.kler.cn/a/412643.html

相关文章:

  • Adaboost集成学习 | Python实现基于NuSVR-Adaboost多输入单输出回归预测
  • 红外小目标检测
  • nodepad配置c/c++ cmd快速打开创建项目文件
  • Python数据分析实例五、US 大选捐款数据分析
  • 深度学习——3种常见的Transformer位置编码【sin/cos、基于频率的二维位置编码(2D Frequency Embeddings)、RoPE】
  • 加菲工具 - 好用免费的在线工具集合
  • 工业网络安全 智能电网,SCADA和其他工业控制系统等关键基础设施的网络安全(总结)
  • 无法通过外网连接访问mysql问题排查
  • 如何通过终端连接无线网
  • echarts使用示例
  • laravel官方升级引起的报错问题解决
  • 原子类、AtomicLong、AtomicReference、AtomicIntegerFieldUpdater、LongAdder
  • [python]poetry安装和使用
  • Vue前端面试进阶(五)
  • day29|leetcode 134. 加油站 , 135. 分发糖果 ,860.柠檬水找零 , 406.根据身高重建队列
  • 模型压缩理论简介及剪枝与稀疏化在 征程 5 上实践
  • 检测到“runtimelibrary”的不匹配项: 值“mtd_staticdebug”不匹配值“mdd_dynamic”
  • 基于MFC实现的俄罗斯方块游戏
  • cgroup简介
  • 深入理解 TypeScript:联合类型与交叉类型的应用
  • 如何编写出色的技术文档
  • shell(4)脚本与用户交互以及if条件判断
  • 第三十二章 UDP 客户端 服务器通信
  • 神经网络的数学——一个完整的例子
  • 《热带气象学报》
  • Android 手写签名板