Flutter 组件集录 | RawMagnifier 组件 - 拿起你的八倍镜

news2024/11/23 9:07:57

theme: cyanosis

1. 前言

今天看 Flutter 源码,偶然发现 Magnifier 组件,这单词不就是 放大镜 嘛! 再结合新版 Flutter 中输入文本的放大镜效果,直觉告诉我这玩意应该可以放大任何组件。如下所示,背景是一张图片,使用 RawMagnifier 实现了点击拖拽局部放大的效果,看起来还是蛮酷的:

140.gif

另外,也可以自定义放大镜的形状,如下的五角星:

141.gif

该组件已收录入 FlutterUnit ,可以在应用中查看相关源码:

| 桌面端 | 移动端 | | --- | --- | | | |


2. RawMagnifier 组件的简单使用

下面来简单使用一下:案例中通过 Stack 将 Image 和 RawMagnifier 叠放在一起,并且居中对齐。可以看到 RawMagnifier 组件的展示内容是对应图片位置的局部放大图。是不是用起来非常简单,就能实现很酷的效果:

image.png

```dart class MagnifierExampleApp extends StatelessWidget{ final Size magnifierSize = const Size(120, 120);

const MagnifierExampleApp({super.key});

@override Widget build(BuildContext context) { return Scaffold( body: Center( child: Stack( alignment: Alignment.center, children: [ Image.asset('assets/images/sabar_bar.webp'), _buildMagnifier(), ], ), ), ); }

Widget _buildMagnifier(){ return RawMagnifier( decoration: const MagnifierDecoration( shape: CircleBorder( side: BorderSide(color: Colors.blue, width: 2), ), ), size: magnifierSize, magnificationScale: 3, ); } } ```

强调一点,它可以放大和其叠放的 任何组件 ,比如其下放置一个文本组件,展示 张风捷特烈

image.png


3. RawMagnifier 组件的构造函数

了解了简单使用,下面瞄一眼 RawMagnifier 组件源码中定义的入参,它继承自 StatelessWidget ,看起来并不是很复杂。

image.png

| 属性名 | 类型 | 介绍 | 默认值 | --- | --- |--- |--- | | child | Widget? | 子组件 | null | | decoration | MagnifierDecoration | 装饰对象 | MagnifierDecoration() | | magnificationScale | double | 放大倍数 | 1 | | size | Size | 放大镜尺寸 | required | | focalPointOffset | Size | 中心偏移量 | Offset |


其中尺寸和放大倍数非常好理解,如下 size 改成 150*150、放大倍数 magnificationScale 改成 8 倍 :

image.png

focalPointOffset 表示放大中心的偏移量,如下所示偏移量设为 Offset(-10,0), 效果上来看局部区域显示的靠左一点的内容 :

image.png


decoration 是一个比较重要的属性,类型为 MagnifierDecoration 。可以配置装饰效果:从源码来看,可以定义放大镜的透明度、阴影和形状:

image.png

如下所示,0.9 的透明度可以看出一点底部的图案,去掉了边线。添加阴影:

image.png

dart Widget _buildMagnifier(){ return RawMagnifier( decoration: MagnifierDecoration( opacity: 0.9, shadows: [ BoxShadow( offset: Offset(1,1), blurRadius: 4, spreadRadius: 6, color: Colors.black.withOpacity(0.1) ) ], shape: CircleBorder(), ), size: magnifierSize, focalPointOffset: Offset(-10, 0), magnificationScale: 3, ); }


除此之外, MagnifierDecoration 还有一个 shape 属性,类型为 ShapeBorder,可以设置放大镜的形状。在 《【Flutter高级玩法-shape】Path在手,天下我有》 一文中详细介绍了该类型的使用。比如下面自定义一个五角星的形状:

image.png

```dart class _StarShapeBorder extends ShapeBorder { final Path _path = Path();

@override EdgeInsetsGeometry get dimensions => EdgeInsets.zero;

@override Path getInnerPath(Rect rect, {TextDirection? textDirection}) { return Path(); }

@override Path getOuterPath(Rect rect, {TextDirection? textDirection}) => nStarPath(5, rect.height / 2, rect.height / 2 * 0.5, dx: rect.width / 2, dy: rect.height / 2);

@override void paint(Canvas canvas, Rect rect, {TextDirection? textDirection}) { Paint paint = Paint()..style=PaintingStyle.stroke..color=Colors.blue..strokeWidth =2; canvas.drawPath(getOuterPath(rect), paint); }

Path nStarPath(int num, double R, double r, {dx = 0, dy = 0}) { double perRad = 2 * pi / num; double radA = perRad / 2 / 2; double radB = 2 * pi / (num - 1) / 2 - radA / 2 + radA; _path.moveTo(cos(radA) * R + dx, -sin(radA) * R + dy); for (int i = 0; i < num; i++) { _path.lineTo( cos(radA + perRad * i) * R + dx, -sin(radA + perRad * i) * R + dy); _path.lineTo( cos(radB + perRad * i) * r + dx, -sin(radB + perRad * i) * r + dy); } _path.close(); return _path; }

@override ShapeBorder scale(double t) => this; } ```


4. 手势交互

上面就是 RawMagnifier 组件的使用方式,那如何实现按下展示放大镜、拖拽更新位置、抬起取消呢?答案很简单:监听手势事件。首先,由于需要在手势交互中更新位置和显示信息,所以需要 StatefulWidget 进行处理;然后添加如下两个状态数据用于表示放大镜位置和是否显示:

dart Offset _dragGesturePosition = Offset.zero; bool _show = false;

然后通过 GestureDetector 组件监听拖拽事件、通过 Positioned 组件控制放大镜的位置:

image.png

最后在手势交互中更新两个状态数据即可:

dart void _onPanDown(DragDownDetails details) { _dragGesturePosition = details.localPosition-Offset(magnifierSize.width/2,magnifierSize.height/2); _show = true; setState(() { }); } void _onPanEnd(DragEndDetails details) { setState(() => _show = false); } void _onPanUpdate(DragUpdateDetails details) { _dragGesturePosition = details.localPosition-Offset(magnifierSize.width/2,magnifierSize.height/2); setState(() { }); } void _onPanCancel() { setState(() => _show = false); }


5. Magnifier 组件

总的来说 RawMagnifier 的使用方式还是比较简单的,表现效果却非常炫酷。另外,基于 RawMagnifier 组件,官方还提供了一个 Magnifier 组件便于使用,从源码中可以看出它在构造函数在给了默认的参数:

image.png

从构建逻辑中可以看出 Magnifier 组件只是借用了 RawMagnifier 组件,提供一个圆角矩形的装饰形状而言,没有什么非常特别的。

image.png

至于 RawMagnifier 内部的实现原理,有机会再单独分析一下。那本文就到这里,谢谢观看~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/668921.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

0013-TIPS-pawnyable : Race-Condition

原文 Linux Kernel PWN | 040204 Pawnyable之竞态条件 Holstein v4: Race Condition 题目下载 漏洞代码 #include <linux/module.h> #include <linux/kernel.h> #include <linux/cdev.h> #include <linux/fs.h> #include <linux/uaccess.h> #i…

使用 Vite + Vue3 + Element-Plus + Pinia + Ts 搭建 Vue3 项目

使用 Vite Vue3 Element-Plus Pinia Ts 搭建 Vue3 项目 使用Vite搭建配置Router配置 Element-Plus配置sass配置Pinia配置解析 符号&#xff0c;并找到对应的路径TypeScript忽略类型检查 使用Vite搭建 Vite 需要 Node.js 版本 14.18&#xff0c;16。然而&#xff0c;有些模…

chatgpt赋能python:Python指定小数点位数的完整指南

Python指定小数点位数的完整指南 Python是一种高级编程语言&#xff0c;广泛用于科学、统计和数学计算。在许多情况下&#xff0c;我们需要对浮点数进行更精确的计算。Python 中保留小数位数的能力很强&#xff0c;本文将向您介绍如何在 Python 中指定小数点后的位数。 为什么…

购买服务器/安装宝塔

1、服务器的选择 本人知道并了解一丢丢的就这四个平台&#xff1a; 1、阿里云 2、腾讯云 3、硅云 4、亚马逊 个人觉得阿里云是YYDS&#xff0c;啥都挺方便的&#xff0c;唯一不足就是有点小贵&#xff0c;但是新用户第一次购买还是很优惠的。 腾讯云有的云服务器是真的便宜&am…

【Batch_size 与 梯度 之间的关系】

chatGPT 回答 梯度更新与批大小&#xff08;batch size&#xff09;之间有密切的关系。批大小是指在训练过程中一次迭代所使用的样本数量。 在深度学习中&#xff0c;梯度下降是一种常用的优化算法&#xff0c;用于更新模型参数以最小化损失函数。梯度是损失函数对于模型参数…

Gradio Flagging模块解析与实践

❤️觉得内容不错的话&#xff0c;欢迎点赞收藏加关注&#x1f60a;&#x1f60a;&#x1f60a;&#xff0c;后续会继续输入更多优质内容❤️ &#x1f449;有问题欢迎大家加关注私戳或者评论&#xff08;包括但不限于NLP算法相关&#xff0c;linux学习相关&#xff0c;读研读博…

基于html+css的图展示135

准备项目 项目开发工具 Visual Studio Code 1.44.2 版本: 1.44.2 提交: ff915844119ce9485abfe8aa9076ec76b5300ddd 日期: 2020-04-16T16:36:23.138Z Electron: 7.1.11 Chrome: 78.0.3904.130 Node.js: 12.8.1 V8: 7.8.279.23-electron.0 OS: Windows_NT x64 10.0.19044 项目…

大数据大作业(课程设计)

题目&#xff1a;信息爬取字数统计及可视化 内容及要求&#xff1a; 配置Hadoop平台&#xff1b;利用爬虫技术爬取任一门户网站新闻栏目一定时间段内的新闻信息&#xff0c;保存为一个或多个文件并上传到Hadoop平台以本人学号命名的文件夹下&#xff1b;利用MapReduce框架编程完…

CSS3-显示模式

显示模式 1 块级显示 2 行内显示 3 行内块显示 4 元素显示模式转换 5 拓展 1 块级显示 属性&#xff1a;display:block 显示特点&#xff1a; 1 独占一行&#xff08;一行只能显示一个&#xff09; 2 宽度默认是父元素的宽度&#xff0c;高度默认由内容撑开 3 可以设置宽高 代表…

Cortext-M3系统:异常系统(5)

1、使用中断 在CM3中&#xff0c;NVIC为我们搞定了使用中断时的很多例行任务&#xff0c;如优先级检查、入栈/出栈、取向量等。不过在NVIC能行使职能之前&#xff0c;还需要我们做好如下的初始化工作&#xff1a;建立堆栈、建立向量表、分配各中断的优先级、使能中断。 1.1 建…

node笔记_读取目录的文件

文章目录 ⭐前言⭐fs.readdirSync&#x1f496; 读取目录 不加withFileTypes&#x1f496; 读取目录 加withFileTypes&#x1f496; 读取目录时 判断元素文件还是目录 ⭐结束 ⭐前言 大家好&#xff0c;我是yma16&#xff0c;本文分享关于node读取目录文件 往期文章 node_wind…

【java】Jconsole 开启远程连接遇到的一些坑

文章目录 背景一、JMX二、配置远程连接2.1、Java 程序启动2.2、tomcat 启动2.3、无法远程问题排查2.4、解决方案 三、关闭 tomcat 报错3.1、问题分析3.2、问题解决 总结 背景 最近在学习 JVM&#xff0c;其中涉及到性能、内存等指标分析需要使用工具分享&#xff0c;Java 提供…

dvwa靶场通关(六)

第六关&#xff1a;Insecure CAPTCHA&#xff08;不安全的验证码&#xff09; 不安全的验证码&#xff1f;不是这个意思&#xff0c;而是指验证码验证可以被绕过。怎么绕&#xff1f;一般都是验证码的验证和最终修改的验证分离&#xff0c;导致了中间过程&#xff08;验证码的…

io.netty学习(八)零拷贝原理

目录 零拷贝 传统I/O操作存在的性能问题 零拷贝技术原理 虚拟内存 mmap/write 方式 sendfile 方式 带有 scatter/gather 的 sendfile方式 splice 方式 总结 io.netty学习使用汇总 零拷贝 零拷贝&#xff08;Zero-Copy&#xff09;是一种 I/O 操作优化技术&#xff0c…

总结906

学习目标&#xff1a; 月目标&#xff1a;6月&#xff08;线性代数强化9讲&#xff0c;背诵15篇短文&#xff0c;考研核心词过三遍&#xff09; 周目标&#xff1a;线性代数强化3讲&#xff0c;英语背3篇文章并回诵&#xff0c;检测 每日规划 今日已做&#xff1a; 1.回环背诵…

chatgpt赋能python:Python捕捉按键:探索基础和应用

Python捕捉按键&#xff1a;探索基础和应用 Python作为高级编程语言&#xff0c;可以用于各种任务&#xff0c;例如数据分析、机器学习、图形用户界面等等。其中&#xff0c;捕捉用户键盘输入是一个常见的任务&#xff0c;它可以用于实现简单的游戏、命令行应用和用户交互&…

Redis持久化说明及其单台Linux服务器搭建Redis集群架构

一.Redis持久化方式 1.1 RDB快照 说明&#xff1a;RDB快照主要以二进制文件的形式进行存储数据&#xff0c;主要以文件名dump.rdb进行存储&#xff0c;主要设置redis.conf里面设置’save 60 1000’命令可以开启&#xff0c; 表示在60秒内操作1000次进行一次备份数据。在客户端…

《网络安全0-100》网络安全工具

网络安全工具 抓包工具 抓包工具是网络安全领域中常用的一种工具&#xff0c;用于捕获和分析网络数据包&#xff0c;帮助用户了解网络流量、发现网络攻击和漏洞等问题。以下是几个常用的抓包工具&#xff1a; Wireshark&#xff1a;Wireshark是一种开放源代码的网络协议分析工…

软考A计划-系统集成项目管理工程师-信息化知识(五)

点击跳转专栏>Unity3D特效百例点击跳转专栏>案例项目实战源码点击跳转专栏>游戏脚本-辅助自动化点击跳转专栏>Android控件全解手册点击跳转专栏>Scratch编程案例点击跳转>软考全系列 &#x1f449;关于作者 专注于Android/Unity和各种游戏开发技巧&#xff…

Unity核心6——Animation

一、动画窗口 ​ 通过 Window --> Animation --> Animation 打开 Animation 窗口 ​ Animation窗口主要用于在 Unity 内部创建和修改动画&#xff0c;所有在场景中的对象都可以通过 Animation 窗口为其制作动画 ​ 原理&#xff1a; ​ 制作动画时&#xff1a;记录在…