【绘制 widget】Flutter FractionalTranslation

简介: 【绘制 widget】Flutter FractionalTranslation

image.png


大家好,我是 17。今天的每日 widget 为大家介绍 FractionalTranslation。

FractionalTranslation 可以按比例偏移 child,在 Animation 的加持下,可以实现直线滑动的动画效果,比如 SlideTransition 就是这样实现的动画效果。

FractionalTranslation 介绍

FractionalTranslation 继承自 SingleChildRenderObjectWidget。renderObject 是 RenderFractionalTranslation 类的实例。RenderFractionalTranslation extends RenderProxyBox 没有 override PerformLayout 方法,所以布局方面没有什么建树。 如果有 child,透传 Constrains 给 child,size 和 child 一样大。他的能力是在绘制阶段完成的。

源码分析

@override
  void paint(PaintingContext context, Offset offset) {
    assert(!debugNeedsLayout);
    if (child != null) {
      super.paint(
          context,
          Offset(
            offset.dx + translation.dx * size.width,
            offset.dy + translation.dy * size.height,
          ));
    }
  }
复制代码

逻辑还是很简单的,就是绘制的时候在 x 轴方向加上偏移  translation.dx * size.width ,在 y 轴方向加上偏移 translation.dy * size.height

@override
  bool hitTest(BoxHitTestResult result, {required Offset position}) {
    return hitTestChildren(result, position: position);
  }
 @override
 bool hitTestChildren(BoxHitTestResult result, {required Offset position}) {
    assert(!debugNeedsLayout);
    return result.addWithPaintOffset(
      offset: transformHitTests
          ? Offset(translation.dx * size.width, translation.dy * size.height)
          : null,
      position: position,
      hitTest: (BoxHitTestResult result, Offset position) {
        return super.hitTestChildren(result, position: position);
      },
    );
}
复制代码

FractionalTranslation 能否通过点击测试完全取决于 child。

transformHitTests 为 false,点击 child 溢出的部分不会通过 hitTest。

transformHitTests 为 true,对 dx,dy 做了偏移,抵消掉了绘制的时候 child 偏移的影响。 点击 child 溢出的部分会通过 hitTest。

使用 FractionalTranslation

image.png

Center(
child: Container(
    foregroundDecoration:
        BoxDecoration(border: Border.all(color: Colors.red)),
    child: FractionalTranslation(
      transformHitTests: true,
      translation: Offset(0.5, 0),
      child: GestureDetector(
          onPanDown: (details) {
            print(
                '${details.globalPosition}--${details.localPosition}');
          },
          child: Container(
            width: 100,
            height: 100,
            color: Colors.blue,
          )),
)));
复制代码

红色部分是 FractionalTranslation 的 size,大小为 Size(100,100),参数 Offset(0.5, 0) 让 child 向右偏移 100*0.5= 50。偏移的值也可以为负,比如 Offset(-0.5, 0) 就会向左偏移 50。

虽然在视觉上 child 超出右边 50,但是所占的位置 在 layout 阶段就已经确定了,所以无论 child 如何偏移,FractionalTranslation 所占的位置都是红框部分。

参数 transformHitTests 会影响到 localPosition 。如果为 true(默认值)localPosition 的值是相对于 child 的左上角的。否则相对于 FractionalTranslation 的左上角。transformHitTests 对 globalPosition 没有影响。

关于点击范围

FractionalTranslation size 内的 child 是可以点击的,只要父级的 size 都包含了 child。溢出的部分能否点击取决于父级的 size 是多大 并且 FractionalTranslation 的参数 transformHitTests: true。只要所有的父级都包含了 child 溢出的部分,溢出的部分也是可以点击的。因为点击测试是从顶层向下层发起的,进行深度优先遍历,如果pointerEvent 在上层某个 widget 的 size 之外,那么在上层就不会再调用 child 的 hitTest,下面的 children 就没有机会参加 hitTest,当然也就没有机会通过 hitTest 了。

目录
相关文章
|
Dart 测试技术 开发工具
了解 Flutter 的 Timer 类和 Timer.periodic【Flutter 专题 19】
在构建移动应用程序时,我们经常会遇到必须在一定时间后执行任务的场景。还记得在进入应用程序之前看到闪亮的启动画面吗? 或者我们可能需要一段代码在一段时间后重复执行,比如显示剩余时间限制以填充一次性密码或每秒更改小部件的颜色以创建漂亮的动画。
6103 0
|
3月前
|
数据采集 存储 前端开发
5分钟学会用Python爬取知乎热榜:从零开始的实战指南
免费提供Python与PyCharm安装包,助你零成本开启编程之旅!链接:https://pan.quark.cn/s/48a86be2fdc0
606 0
|
3月前
|
Java 数据库连接 开发者
Spring Framework 核心技术详解
本文档旨在深入解析 Java Spring Framework 的核心技术原理与应用。与侧重于快速开发的 Spring Boot 不同,本文将聚焦于 Spring 框架本身的设计理念、核心容器、控制反转(IoC)、面向切面编程(AOP)、数据访问与事务管理等基础且强大的模块。通过理解这些核心概念,开发者能够更深刻地领悟 Spring 生态系统的设计哲学,并具备解决复杂企业级应用开发问题的能力。
283 4
|
5月前
|
区块链
小试牛刀-区块链Solana多签账户
在 Solana 区块链中,多签账户(Multisig Account)是一种智能合约账户,允许多个签名者共同管理和控制账户上的资产或操作。这种机制增强了账户的安全性和灵活性,特别适用于需要多个权限共同批准的操作场景,如资产管理、资金转移、或项目治理。
268 1
|
7月前
|
XML 搜索推荐 Android开发
Android改变进度条控件progressbar的样式(根据源码修改)
本文介绍了如何基于Android源码自定义ProgressBar样式。首先分析了系统源码中ProgressBar样式的定义,发现其依赖一张旋转图片实现动画效果。接着分两步指导开发者实现自定义:1) 模仿源码创建一个旋转动画XML文件(放置在drawable文件夹),修改图片为自定义样式;2) 在UI控件中通过`indeterminateDrawable`属性应用该动画。最终实现简单且个性化的ProgressBar效果,附带效果图展示。
510 2
|
开发工具 UED 容器
Flutter&鸿蒙next 实现长按录音按钮及动画特效
本文介绍了如何在 Flutter 中实现一个带有动画效果的长按录音按钮。通过使用 `GestureDetector` 监听长按手势,结合 `AnimatedContainer` 和 `AnimationController` 实现按钮的动画效果,以及 `flutter_sound` 插件完成录音功能。文章详细讲解了功能需求、实现思路和代码实现,帮助读者逐步掌握这一实用功能的开发方法。
510 5
|
网络协议 网络安全 网络虚拟化
WireGuard 系列文章(四):WireGuard 快速上手
WireGuard 系列文章(四):WireGuard 快速上手
|
缓存 关系型数据库 MySQL
error: Failed dependencies: mariadb-connector-c-config is obsoleted by mysql-community-server-8.0.36-1.el7.x86_64 问题解决
error: Failed dependencies: mariadb-connector-c-config is obsoleted by mysql-community-server-8.0.36-1.el7.x86_64 问题解决
989 19
|
Java 数据安全/隐私保护 Docker
Docker Desktop 启动报错 Unexpected WSL error 问题解决
Docker Desktop 启动报错 Unexpected WSL error 问题解决
好看简单的Login登录界面,背景色带渐变
好看简单的Login登录界面,背景色带渐变
579 2