Flutter 组件使用:使用 Stack 替代 GlobalKey 的定位 tip-widget 实现

news/2024/11/22 6:05:58/

场景

有时候需要在指定位置进行 tip-widget 的弹出与展示,常见的方式是通过给指定位置上的指定 widget 添加 GlobalKey 来实现;

但是,使用这种方式的话,【一】大多数时候都需要进行全局定位转换(localToGlobal)及计算,【二】使用系统 Popup 控件,当 Popup 展示时,列表可能不可滑动,【三】如果需要跟随列表滑动,就需要使用实时监听滑动回调的方式去实时更新 tip-widget 的实时跟随滑动;

以上提到的问题,不仅实现上“费时费力”,还会使相关功能代码分散、不相关功能代码耦合,造成代码维护及迭代上的难度;

所以,在此提出一种“使用 Stack 替代 GlobalKey 的定位 tip-widget 实现”,通过一种“讨巧”的方式,尝试较好地解决以上提到的问题;

当然,解决方法还有很多,骚操作是程序员的乐趣,但是更好地解决问题才是程序员的追求 ~!

效果

在这里插入图片描述

说明

这种方案,是通过使用 Stack 将指定 widget 与 tip-widget 进行绑定,主要有两种场景
1、如果指定 widget 本身的父 widget 就是 Stack 的话,直接把 tip-widget 加入 Stack 进行定位维护就行
2、如果指定 widget 本身的父 widget 不是 Stack 的话,就使用一个 Stack 包裹住指定 widget,然后保证 Stack 的宽高为指定 widget 的宽高,同时设置 Stack 的 clipBehavior 为 Clip.none,最后把 tip-widget 加入 Stack 进行定位维护

如果指定 widget 本身的父 widget 不是 Stack 的话,需要注意以下限定条件
并不是所有场景都适合使用这种方案进行适配,需要根据指定 widget 的父 widget 的布局特点进行选用

比如 Column 控件,Column 控件对于子 widget 的绘制顺序是由上向下(逻辑在 RenderFlex 的 performLayout() 和 paint(PaintingContext context, Offset offset) 中);
正常情况下,Column 子 widget 间是根据其本身在 Column 中的偏移量紧密衔接的;
但是,如果使用 Stack 的 Clip.none 特性后,Stack 包裹的内容可超范围绘制显示,这时,体现在 Column 的绘制顺序的话,顺序靠后的子 widget 就会覆盖顺序靠前的子 widget 的超范围绘制的内容;
所以,在 Column 中如果 tip-widget 是向上展示的,一般能正常展示,但是,如果 tip-widget 是向下展示的,就会有覆盖的问题。

在这里插入图片描述

范例

class _TestPageState extends State<TestPage> {bool show = false;void initState() {super.initState();}Widget build(BuildContext context) {return Scaffold(appBar: AppBar(title: const Text('Stack妙用')),body: SingleChildScrollView(child: Column(children: [Container(width: double.maxFinite,height: 150,color: Colors.red.withOpacity(0.5),),Container(width: double.maxFinite,height: 150,color: Colors.orange.withOpacity(0.5),),Container(alignment: Alignment.center,width: double.maxFinite,height: 150,color: Colors.yellow.withOpacity(0.5),child: Container(color: show ? Colors.red : null,child: Stack(clipBehavior: Clip.none,children: [GestureDetector(child: const Icon(Icons.add_circle, size: 50),onTap: () {setState(() {show = !show;});},),if (show)Positioned(top: -90,left: 30,child: Container(alignment: Alignment.center,color: Colors.red.withOpacity(0.8),width: 50,height: 80,child: const Text('菜单'),),),if (show)Positioned(top: 60,left: 30,child: Container(alignment: Alignment.center,color: Colors.red.withOpacity(0.8),width: 50,height: 80,child: const Text('菜单'),),),],),),),Container(width: double.maxFinite,height: 150,color: Colors.green.withOpacity(0.5),),Container(width: double.maxFinite,height: 150,color: Colors.blue.withOpacity(0.5),),Container(width: double.maxFinite,height: 150,color: Colors.indigo.withOpacity(0.5),),Container(width: double.maxFinite,height: 150,color: Colors.purple.withOpacity(0.5),),],),),);}
}

http://www.ppmy.cn/news/59501.html

相关文章

OD工具之动态逆向分析技术实例分析

OD工具之动态逆向分析技术实例分析 vscode等编写cmp.cOD工具打开cmp.exe 卧槽垃圾高级软件工程真是烦人还是记录一下吧那么简单的几行没有手册搞半天都无力吐槽了 vscode等编写cmp.c 在vscode等编辑器中编写cmp.c文件&#xff1a; #include<stdio.h> int main() {int …

计算机电脑中了勒索病毒怎么办,Windows系统中了faust勒索病毒解密数据恢复

电脑的操作系统被恶意软件攻击已不再是新鲜的话题了。而攻击的恶意软件中有一种叫做faust勒索病毒&#xff0c;常常袭击Windows电脑系统。如果我们的电脑在使用Windows操作系统时感染了faust勒索软件&#xff0c;请不要慌张&#xff0c;我们可以咨询专业的数据恢复厂商&#xf…

【Qt5】多线程串口

文章目录 原版代码工程增加QCustomplot实时画图的源码工程源码 原版代码工程 源码下载链接&#xff1a; 链接&#xff1a;https://pan.baidu.com/s/15pWzadPwOx_OfJGtvL-MjA 提取码&#xff1a;lief –来自百度网盘超级会员V5的分享 增加QCustomplot实时画图的源码工程 源码&…

Vue第一章:基本概念

一.关于Vue的说法正确的是 v-for指令基于一个数组来渲染一个列表v-for指令需要使用item in items形式的特殊语法&#xff0c;其中items是源数据数组&#xff0c;而item则是被迭代的数组元素的别名v-for在使用的时候最好添加key&#xff0c;且key最好不是索引可以用v-for来遍历…

USB协议分析仪

1 ULPI PHY passive sniffing mode 概念: non driving, no pull-up, no pull-down Function Control.opMode 1; // non-Driving OTG Control.DpPulldown 0; // no pull-down OTG Control.DmPulldown 0; // no pull-down USB IO.ChargerPullupEnDP 0; // no pull-up USB IO.…

JavaEE 第二周

计算机Z20-第2周作业 总分&#xff1a;100分 得分&#xff1a;100.0分 1 . 单选题 中等 15分 下面关于JSP注释的说法中&#xff0c;正确的是&#xff08;&#xff09; A.JSP注释语法格式&#xff1a;<!-- 注释信息 --> B.JSP注释不会发送到…

Java 的简要介绍及开发环境的搭建(超级详细)

图片来源于互联网 目录 | CONTENT Java 简介 一、什么是 Java 二、认识 Java 版本 三、选择哪个版本比较好 搭建 Java 开发环境 一、下载 Java 软件开发工具包 JDK 二、配置环境变量 自动配置 手动配置 三、下载合适的 IDE IntelliJ IDEA Visual Studio Code Eclip…

第十六章 预制件prefab(上)

本章节我们介绍一下“预制件”&#xff0c;也有人叫“预制体”&#xff0c;也就是Prefab。在游戏世界中&#xff0c;那些自然环境的游戏对象&#xff0c;我们可以提前创建在场景中&#xff0c;这个大家能够理解。但是&#xff0c;有些游戏对象&#xff0c;需要根据游戏逻辑来通…