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包裹底部可滚动组件,然后监听用户的滑动,当滑动到了最顶部且继续向下滑动就将SingleChildScrollViewphysics设置为不可滚动
  • 同时改变内容的高度,同时也要改变transitionAnimationController.value的值这样内容区才会跟着移动,缩放
  • 最后在触摸结束的时候进行判断是需要收起弹窗还是关闭弹窗

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

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

相关文章

HD系列边缘网关,助力工商业储能发展!

HD系列边缘网关具备低功耗、高性能、接口丰富等特点&#xff0c;可以实现如通信规约转换、远程调度、智能监测、通信管理等多种应用&#xff0c;适用于储能系统的能源管理系统。 1.1硬件接口 该产品板载瑞芯微 RK3568 处理器&#xff0c;可选配2G16G/432 等配置。机壳采用标准 …

sql:SQL优化知识点记录(十四)

&#xff08;1&#xff09;索引失效行锁变表锁 建立2个索引 索引是失效后&#xff0c;系统性能会变查&#xff0c;如果涉及到锁的话&#xff0c;行锁会变表锁 有一个问题&#xff0c;当session1用b字段做查询条件因为是varchar类型&#xff0c;需要加双引号&#xff0c;但是没…

GO语言网络编程(并发编程)并发介绍,Goroutine

GO语言网络编程&#xff08;并发编程&#xff09;并发介绍&#xff0c;Goroutine 1、并发介绍 进程和线程 A. 进程是程序在操作系统中的一次执行过程&#xff0c;系统进行资源分配和调度的一个独立单位。 B. 线程是进程的一个执行实体,是CPU调度和分派的基本单位,它是比进程更…

sqlserver 各种集合、区间、 时间轴(持更)

1.所有有交集的区间 场景&#xff1a;在事件表里查找某年员工的岗位系数&#xff0c;并计算其加权平均数。case1&#xff1a;该员工是老员工&#xff0c;从2020年一直到2049年。case2&#xff1a;该员工是老员工&#xff0c;但是今年离职。case3&#xff1a;该员工是今年的新员…

线程池|单例模式|STL、智能指针线程安全|读者写者问题

线程池 线程池的逻辑思想&#xff1a; 每当我们处理一个任务就要创建一个线程&#xff0c;创建线程的开销是很大的。因此我们可以预先创建一批线程&#xff0c;任务队列里没有任务的时候&#xff0c;每个线程都休眠&#xff0c;当队里中有任务的时候&#xff0c;就可以唤醒线程…

YOLOV7改进-针对小目标的NWD(损失函数)

link 1、复制这些 2、utils-loss&#xff0c;这里加 3、把这几行复制到utiils的loss.py 4、先对CoputerLoss类做修改 5、把那一行替换成这个 6、修改 7、iou_ration是超参&#xff0c;可以调&#xff0c;如果小目标比较多的话&#xff0c;这个值可以低一些&#xff0c;…

入门人工智能 —— 学习 python 使用 IDE :vscode 完成编程 (2)

入门人工智能 —— 学习 python 使用 IDE &#xff1a;vscode 完成编程 &#xff08;2&#xff09; 安装和配置 VSCode创建和运行 Python 代码使用 VSCode 的调试功能 在上一篇文章中&#xff0c;介绍了如何入门人工智能编程&#xff0c;并开始了学习 Python 编程语言的基础知识…

英诺森 “供应链智能数据平台”荣获“科技进步奖”

近日&#xff0c;2023年中国物流与采购联合会科学技术奖正式公布&#xff0c;该奖项经国家科技部批准&#xff0c;在国家科学技术奖励工作办公室登记备案&#xff0c;是我国物流行业最具影响力的奖项之一。 英诺森联合客户申报的科技项目“英诺森供应链智能数据平台”&#xf…

1.1 计算机网络在信息时代中的作用

思维导图&#xff1a; 正文&#xff1a; 我的理解&#xff1a; 这段话是一本书或课程的第一章简介&#xff0c;它的目的是为读者或学生提供一个关于计算机网络基础知识的框架或大纲。 首先&#xff0c;它强调了这章是整本书的一个概览&#xff0c;会先介绍计算机网络在信息时…

Python 操作 Excel

之前看过一篇文章&#xff0c;说一个工作多年的老员工&#xff0c;处理数据时只会用复制粘贴到 Excel &#xff0c;天天加班工作还完不成&#xff0c;后来公司就招了一个会 Python 的新人&#xff0c;结果分分钟就处理完成。所以工作中大家经常会使用 Excel 去处理以及展示数据…

C# WPF 自己写的一个模拟病毒传播的程序,有可视化

源代码: https://github.com/t39q/VirusSpread 主要代码 using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks;namespace VirusSpread.Bu…

C/C++苹果和虫子 2019年9月电子学会青少年软件编程(C/C++)等级考试一级真题答案解析

目录 C/C苹果和虫子 一、题目要求 1、编程实现 2、输入输出 二、解题思路 1、案例分析 三、程序代码 四、程序说明 五、运行结果 六、考点分析 C/C苹果和虫子 2019年9月 C/C编程等级考试一级编程题 一、题目要求 1、编程实现 你买了一箱n个苹果&#xff0c;很不幸…

Android Automotive编译

系统准备 安装系统 准备一台安装Ubuntu系统的机器&#xff08;windows系统的机器可以通过WSL安装ubuntu系统&#xff09; 安装docker 本文使用docker进行编译&#xff0c;因此提前安装docker。参考网络链接安装docker并设置为不使用sudo进行docker操作。 参考链接&#xff…

分类算法系列④:朴素贝叶斯算法

目录 1、贝叶斯算法 2、朴素贝叶斯算法 3、先验概率和后验概率 4、⭐机器学习中的贝叶斯公式 5、文章分类中的贝叶斯 6、拉普拉斯平滑系数 6.1、介绍 6.2、公式 7、API 8、示例 8.1、分析 8.2、代码 8.3、⭐预测流程分析 &#x1f343;作者介绍&#xff1a;准大三…

Top 15 开源3D分子蛋白质建模与渲染软件

如今&#xff0c;WebGL 是一种趋势技术&#xff0c;因为它允许开发人员使用现代浏览器作为客户端来创建复杂的 3D 交互式图形、游戏&#xff0c;而无需安装额外的插件、扩展或软件。 WebGL允许浏览器直接与GPU&#xff08;图形处理单元&#xff09;一起工作。 推荐&#xff1a;…

HJ48 从单向链表中删除指定值的节点

Powered by:NEFU AB-IN Link 文章目录 HJ48 从单向链表中删除指定值的节点题意思路代码 HJ48 从单向链表中删除指定值的节点 题意 输入一个单向链表和一个节点的值&#xff0c;从单向链表中删除等于该值的节点&#xff0c;删除后如果链表中无节点则返回空指针。 思路 单向链表…

Java——》线程间是如何通信的

推荐链接&#xff1a; 总结——》【Java】 总结——》【Mysql】 总结——》【Redis】 总结——》【Kafka】 总结——》【Spring】 总结——》【SpringBoot】 总结——》【MyBatis、MyBatis-Plus】 总结——》【Linux】 总结——》【MongoD…

企业架构LNMP学习笔记14

默认官方模块&#xff1a; Gzip压缩&#xff1a; 压缩文件&#xff0c;使文件变小了&#xff0c;传输更快了&#xff0c;目前大部分市场浏览器都支持Gzip。 传输的时候省流量。 目的是为了提高用户的加载速度。 #开启gzip压缩 gzip on; #http协议版本 gzip_http_version 1.0…

Java网络编程(二)Socket 套接字(TCP和UDP),以及TCP的回显

Socket 套接字 我们软件工作者&#xff0c;着重编写的是应用层的代码&#xff0c;但是发送这个数据&#xff0c;我们就需要将应用层传输到传输层&#xff0c;也就意味着我们需要调用应用层的API&#xff0c;统称为 Socket API。 套接字的分类&#xff1a; 流套接字&#xff…

百望云亮相服贸会 重磅发布业财税融Copilot

小望小望&#xff0c;我要一杯拿铁&#xff01; 好的&#xff0c;已下单成功&#xff0c;请问要开具发票嘛&#xff1f; 在获得确认的指令后&#xff0c; 百小望AI智能助手 按用户要求成功开具了一张电子发票&#xff01; 这是2023年服贸会国家会议中心成果发布现场&#x…