Flutter 通过BottomSheetDialog实现抖音打开评论区,内容自动上推、缩放效果
一、先来看下实现的效果

- 实现上面的效果需要解决俩个问题
- 当列表进行向下滑动到顶部的时候,继续滑动可以让弹窗向下收起来
- 弹出上下拖动的时候,视图内容跟着上下移动、缩放大小
二、实现弹窗上下滑动的时候,动态改变内容区的位置和大小
- 通过
showModalBottomSheet
显示底部对话框
showModalBottomSheet(context: context,isScrollControlled: true,backgroundColor: Colors.white,transitionAnimationController: _controller,builder: (_) {///省略部分代码...},
);
1、那问题来了,怎么去监听对话框当前显示的高度呢?
可以发现
showModalBottomSheet
有一个transitionAnimationController
参数,这个就是对话框显示的动画控制器了值为[0,1],当全部显示是为1。
那么当将弹窗设为固定高度时,就可以通过这个值进行计算了
- 假设我们顶部留的最小空间为:
宽度 = 屏幕宽度,高度 = 屏幕宽度 / (16 / 9)
,那么对话框的高度就等与屏幕高度 - 顶部高度
///屏幕宽度
double get screenWidth => MediaQuery.of(context).size.width;
///屏幕高度
double get screenHeight => MediaQuery.of(context).size.height;
///顶部留的高度
double get topSpaceHeight => screenWidth / (16 / 9);
///对话框高度
double get bottomSheetHeight => screenHeight - topSpaceHeight;
2、监听对话框高度改变
void initState() {super.initState();_controller = BottomSheet.createAnimationController(this);_controller.addListener(() {final value = _controller.value * bottomSheetHeight;///更新UI_bottomSheetController.sink.add(value);});
}
Widget build(BuildContext context) {final bottom = MediaQuery.of(context).padding.bottom;return ColoredBox(color: Colors.black,child: Stack(children: [StreamBuilder<double>(stream: _bottomSheetController.stream,initialData: 0,builder: (_, snapshot) {return Container(height: screenHeight - snapshot.data!,alignment: Alignment.center,child: Image.network('https://5b0988e595225.cdn.sohucs.com/images/20200112/75b4a498fdaa48c7813419c2d4bac477.jpeg',),);},),],),);
}
通过上面这样处理,内容区的上移和缩小就已经实现了
三、弹窗内容向下滑动,当滑动到顶继续向下滑动时,可以让对话框继续向下滑动(不打断此次触摸事件)
- 这里借鉴了这位博主的解决方案可以先看一下,https://www.jianshu.com/p/4f2d10750f5c
1、在向下滑动到顶,继续向下的时候,动态改变弹窗内部的高度来达到弹窗下拉的效果,这里本来是想通过改变transitionAnimationController.value的值来改变弹窗的高度,但是实际中发现或的效果不理想,不知道为什么
Widget build(BuildContext context) {return StreamBuilder<double>(stream: _dragController.stream,initialData: widget.height,builder: (context, snapshot) {return AnimatedContainer(height: snapshot.data ?? widget.height,duration: const Duration(milliseconds: 50),child: Column(children: [widget.pinedHeader ?? const SizedBox.shrink(),Expanded(child: Listener(onPointerMove: (event) {///没有滚动到顶部不处理if (_scrollController.offset != 0) {return;}///获取滑动到顶部开始下拉的位置_startY ??= event.position.dy;final distance = event.position.dy - _startY!;///弹窗滑动后剩余高度if ((widget.height - distance) > widget.height) {return;}_dragController.sink.add(widget.height - distance);///剩余弹出高度所占百分比final percent = 1 - distance / widget.height;///为了处理图片大小缩放需要使用widget.transitionAnimationController.value = percent;},/// 触摸事件结束 恢复可滚动onPointerUp: (event) {_startY = null;if (snapshot.data! <= widget.height * 0.5) {///下拉到了一半直接关闭widget.transitionAnimationController.animateTo(0,duration: const Duration(microseconds: 250));} else {///未到一半 恢复展示_dragController.sink.add(widget.height);widget.transitionAnimationController.animateTo(1,duration: const Duration(microseconds: 250));}},child: SingleChildScrollView(controller: _scrollController,physics: snapshot.data == widget.height? const ClampingScrollPhysics(): const NeverScrollableScrollPhysics(),child: widget.child,),),),],),);},);
}
2、解决原理:
- 使用
Listener
包裹底部可滚动组件,然后监听用户的滑动,当滑动到了最顶部且继续向下滑动就将SingleChildScrollView
的physics
设置为不可滚动 - 同时改变内容的高度,同时也要改变
transitionAnimationController.value
的值这样内容区才会跟着移动,缩放 - 最后在触摸结束的时候进行判断是需要收起弹窗还是关闭弹窗
相关文章:

Flutter 通过BottomSheetDialog实现抖音打开评论区,内容自动上推、缩放效果
一、先来看下实现的效果 实现上面的效果需要解决俩个问题 当列表进行向下滑动到顶部的时候,继续滑动可以让弹窗向下收起来弹出上下拖动的时候,视图内容跟着上下移动、缩放大小 二、实现弹窗上下滑动的时候,动态改变内容区的位置和大小 通过…...
Python读取TCP的4字节浮点数
Python4字节浮点数读取 背景读取4字节的浮点数总结 背景 用Python的tkinter开发人机界面。机器是MCU的无线服务器端。Python程序为Client,连接MCU TCP server。client发送21个字节帧。按modbusTCP发送。为提高通讯效率,server端在接到client发送来的8位…...

javaee springMVC的简单使用 jsp页面在webapp和web-inf目录下的区别
项目结构 依赖文件 <?xml version"1.0" encoding"UTF-8"?><project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation"http://maven.apache.org/…...

Docker容器技术实战-1
1.docker容器 docker就好比传统的货运集装箱 每个虚拟机都有独立的操作系统,互不干扰,在这个虚拟机里可以跑任何东西 如应用 文件系统随便装,通过Guest OS 做了一个完全隔离,所以安全性很好,互不影响 容器 没有虚拟化…...
LeetCode算法题:2. 两数相加
文章目录 题目描述:通过代码创建新一串新链表: 题目描述: 给你两个 非空 的链表,表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的,并且每个节点只能存储 一位 数字。 请你将两个数相加,并以…...

ResNet 09
一、发展 1989年,Yann LeCun提出了一种用反向传导进行更新的卷积神经网络,称为LeNet。 1998年,Yann LeCun提出了一种用反向传导进行更新的卷积神经网络,称为LeNet-5 AlexNet是2012年ISLVRC 2012(ImageNet Large Sca…...
什么是脚本语言,解释脚本语言的特点和应用领域
1、什么是脚本语言,解释脚本语言的特点和应用领域。 脚本语言是一种编程语言,通常用于自动化任务或脚本。它们通常比传统的编程语言更容易学习和使用,因为它们通常具有更少的语法和更简单的命令。 脚本语言的特点包括: 简单易学…...
selenium 定位不到元素的几种情况
1.动态id定位不到元素for example: //WebElement xiexin_element = driver.findElement(By.id("_mail_component_82_82"));WebElement xiexin_element = driver.findElement(By.xpath("//span[contains(.,写 信)]")); xiexin_element.click(); 上面一段…...
IDEA启动项目很慢,无访问
用idea启动本地项目,然后自测。 今天突然发现用postman访问不到,用浏览器也访问不到,提示信息就跟项目没有启动时一样(启动日志过多,并没有发现是项目没有启完)。 但是用cmd直接启动jar包,访问…...

时序预测 | MATLAB实现TCN-GRU时间卷积门控循环单元时间序列预测
时序预测 | MATLAB实现TCN-GRU时间卷积门控循环单元时间序列预测 目录 时序预测 | MATLAB实现TCN-GRU时间卷积门控循环单元时间序列预测预测效果基本介绍模型描述程序设计参考资料 预测效果 基本介绍 1.MATLAB实现TCN-GRU时间卷积门控循环单元时间序列预测; 2.运行环…...

简单了解ARP协议
目录 一、什么是ARP协议? 二、为什么需要ARP协议? 三、ARP报文格式 四、广播域是什么? 五、ARP缓存表是什么? 六、ARP的类型 6.1 ARP代理 6.2 免费ARP 七、不同网络设备收到ARP广播报文的处理规则 八、ARP工作机制原理 …...
【Linux】Stratis是什么?Stratis和LVM有什么关系和区别?
背景核心特性Stratis与LVM 的联系与区别感谢 💖 背景 在过去,Linux 用户通常依赖于多个工具和技术来管理存储资源,包括 LVM、mdadm、文件系统工具等。这些工具各自有自己的特点和用途,但也带来了复杂性和学习曲线。Stratis 的出现…...
植物大战僵尸修改金币【Steam下版本可行-其他版本未知】
#0.目的找到user1.dat文件,并修改其值 先关闭退出游戏 #1.找到植物大战僵尸的启动快捷方式-鼠标右键-属性-Web文档-URL-[steam://rungameid/3590] 记住这个【3590】 #2.Steam安装位置下有个【userdata】文件夹 #3.找到这个目录【xxxx\Steam\userdata\850524626\…...
GIS:生成Shp文件
/*** 生成shape文件** param shpPath 生成shape文件路径(包含文件名称)* param encode 编码* param geoType 图幅类型,Point和Rolygon* param geoms 图幅集合*/public static void write2Shape(String shpPath, String encode, String geo…...

【日常笔记】使用Server过程中可能遇到的一些问题
使用Server过程中可能遇到的一些问题 1. 如何查找GPU型号与驱动版本之间的关系?2. 如何查看当前Server的内核版本?3. 使用Nvidia过程中可能用到的命令4. 对Jupyter Notebook的一些配置5. TensorFlow的一般操作6. 使用PyTorch的一些操作7. 修改安装源为国…...

【Mysql】给查询记录增加序列号方法
在MySQL 8.0版本中,你可以使用ROW_NUMBER()函数来添加序号。以下是一个示例查询,演示如何添加序号: SELECT ROW_NUMBER() OVER (ORDER BY column_name) AS serial_number,column1, column2, ... FROMyour_table;请将column_name替换为你想要…...

Linux 安装elasticsearch-7.5.1
相关链接 官⽹: https://www.elastic.co/cn/downloads/elasticsearch 下载: wget https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-7.5.1-linux-x86_64.tar.gz 分词器: https://github.com/medcl/elasticsearch-an…...
ElementUI浅尝辄止26:Notification 通知
悬浮出现在页面角落,显示全局的通知提醒消息。 1.如何使用? 适用性广泛的通知栏 //Notification 组件提供通知功能,Element 注册了$notify方法,接收一个options字面量参数,在最简单的情况下,你可以设置tit…...

IDEA新建的Moudle失效显示为灰色
现象:IDEA新建的Moudle失效显示为灰色!!! 解决方案: 1. 右键点击父模块,选择Open Moudle Settings: 2. 点击加号,选择Import Moudle - 导入模块: 3. 找到对应模块的po…...
Protobuf的简单使用
一.protobuf是什么? Protobuf,全称为Protocol Buffers(协议缓冲区),是一种轻量级的数据序列化格式。它由Google开发,用于高效地存储和传输结构化数据。 与其他常见的数据序列化格式(如XML和JS…...

手游刚开服就被攻击怎么办?如何防御DDoS?
开服初期是手游最脆弱的阶段,极易成为DDoS攻击的目标。一旦遭遇攻击,可能导致服务器瘫痪、玩家流失,甚至造成巨大经济损失。本文为开发者提供一套简洁有效的应急与防御方案,帮助快速应对并构建长期防护体系。 一、遭遇攻击的紧急应…...
进程地址空间(比特课总结)
一、进程地址空间 1. 环境变量 1 )⽤户级环境变量与系统级环境变量 全局属性:环境变量具有全局属性,会被⼦进程继承。例如当bash启动⼦进程时,环 境变量会⾃动传递给⼦进程。 本地变量限制:本地变量只在当前进程(ba…...

HTML 列表、表格、表单
1 列表标签 作用:布局内容排列整齐的区域 列表分类:无序列表、有序列表、定义列表。 例如: 1.1 无序列表 标签:ul 嵌套 li,ul是无序列表,li是列表条目。 注意事项: ul 标签里面只能包裹 li…...
C++中string流知识详解和示例
一、概览与类体系 C 提供三种基于内存字符串的流,定义在 <sstream> 中: std::istringstream:输入流,从已有字符串中读取并解析。std::ostringstream:输出流,向内部缓冲区写入内容,最终取…...
【服务器压力测试】本地PC电脑作为服务器运行时出现卡顿和资源紧张(Windows/Linux)
要让本地PC电脑作为服务器运行时出现卡顿和资源紧张的情况,可以通过以下几种方式模拟或触发: 1. 增加CPU负载 运行大量计算密集型任务,例如: 使用多线程循环执行复杂计算(如数学运算、加密解密等)。运行图…...
JDK 17 新特性
#JDK 17 新特性 /**************** 文本块 *****************/ python/scala中早就支持,不稀奇 String json “”" { “name”: “Java”, “version”: 17 } “”"; /**************** Switch 语句 -> 表达式 *****************/ 挺好的ÿ…...

使用 SymPy 进行向量和矩阵的高级操作
在科学计算和工程领域,向量和矩阵操作是解决问题的核心技能之一。Python 的 SymPy 库提供了强大的符号计算功能,能够高效地处理向量和矩阵的各种操作。本文将深入探讨如何使用 SymPy 进行向量和矩阵的创建、合并以及维度拓展等操作,并通过具体…...

初学 pytest 记录
安装 pip install pytest用例可以是函数也可以是类中的方法 def test_func():print()class TestAdd: # def __init__(self): 在 pytest 中不可以使用__init__方法 # self.cc 12345 pytest.mark.api def test_str(self):res add(1, 2)assert res 12def test_int(self):r…...
人工智能--安全大模型训练计划:基于Fine-tuning + LLM Agent
安全大模型训练计划:基于Fine-tuning LLM Agent 1. 构建高质量安全数据集 目标:为安全大模型创建高质量、去偏、符合伦理的训练数据集,涵盖安全相关任务(如有害内容检测、隐私保护、道德推理等)。 1.1 数据收集 描…...

解析奥地利 XARION激光超声检测系统:无膜光学麦克风 + 无耦合剂的技术协同优势及多元应用
在工业制造领域,无损检测(NDT)的精度与效率直接影响产品质量与生产安全。奥地利 XARION开发的激光超声精密检测系统,以非接触式光学麦克风技术为核心,打破传统检测瓶颈,为半导体、航空航天、汽车制造等行业提供了高灵敏…...