Flutter-底部弹出框(Widget层级)

需求
  • 支持底部弹出对话框。
  • 支持手势滑动关闭。
  • 支持在widget中嵌入引用。
  • 支持底部弹出框弹出后不影响其他操作。
  • 支持弹出框中内容固定头部和下面列表时,支持触摸头部并在列表不在头部的时候支持滑动关闭
简述

通过上面的需求可知,就是在界面中可以支持底部弹出一个弹出框,但是又不影响除了这个弹出框外其他操作,同时支持手势滑动关闭。想到这里我们其实会想到一个控件DraggableScrollableSheet,Flutter提供一种可以支持在widget中引入的底部弹出布局,同时不影响其他的操作,所以我就使用这个控件测试了下,发现一个问题,就是当底部弹出框内容为上面有个头部,底部是个列表时,每次都需要列表滑动到顶部的时候才可以手势滑动关闭,所以需要支持触摸顶部布局也支持手势滑动关闭,所以在此控件上做一个修改。

效果

bottom_sheet.gif

代码如下
`import 'package:flutter/material.dart';/// 底部弹出Widget
/// 1、支持手势下拉关闭
/// 2、支持动画弹出收起
/// 3、支持弹出无法关闭
class DragBottomSheetWidget extends StatefulWidget {DragBottomSheetWidget({required Key key,required this.builder,this.duration,this.childHeightRatio = 0.8,this.onStateChange,}) : super(key: key);Function(bool)? onStateChange;final double childHeightRatio;final Duration? duration;final ScrollableWidgetBuilder builder;@overrideState<DragBottomSheetWidget> createState() => DragBottomSheetWidgetState();
}class DragBottomSheetWidgetState extends State<DragBottomSheetWidget>with TickerProviderStateMixin {final controller = DraggableScrollableController();//是否可以关闭bool isCanClose = true;//是否展开bool isExpand = false;double verticalDistance = 0;@overridevoid initState() {super.initState();}@overridevoid dispose() {controller.dispose();super.dispose();}Future show({bool isCanClose = true}) {return controller.animateTo(1,duration: widget.duration ?? const Duration(milliseconds: 200),curve: Curves.linear).then((value) {if (!isCanClose) {setState(() {this.isCanClose = isCanClose;});}});}void hide() {controller.animateTo(0,duration: widget.duration ?? const Duration(milliseconds: 200),curve: Curves.linear,);}void _dragJumpTo(double y) {var size = y / MediaQuery.of(context).size.height;controller.jumpTo(widget.childHeightRatio - size);}void _dragEndChange() {controller.size >= widget.childHeightRatio / 2? controller.animateTo(1,duration: widget.duration ?? const Duration(milliseconds: 200),curve: Curves.linear,): hide();}@overrideWidget build(BuildContext context) {return NotificationListener<DraggableScrollableNotification>(onNotification: (notification) {if (notification.extent == widget.childHeightRatio) {if (!isExpand) {isExpand = true;widget.onStateChange?.call(true);}} else if (notification.extent < 0.00001) {if (isExpand) {isExpand = false;widget.onStateChange?.call(false);}}return true;},child: DraggableScrollableSheet(initialChildSize: isCanClose && !isExpand ? 0 : widget.childHeightRatio,minChildSize: isCanClose ? 0 : widget.childHeightRatio,maxChildSize: widget.childHeightRatio,expand: true,snap: true,controller: controller,builder: (BuildContext context, ScrollController scrollController) {return GestureDetector(behavior: HitTestBehavior.translucent,onVerticalDragDown: (details) {verticalDistance = 0;},onVerticalDragUpdate: (details) {verticalDistance += details.delta.dy;_dragJumpTo(verticalDistance);},onVerticalDragEnd: (details) {_dragEndChange();},child: widget.builder.call(context, scrollController),);},),);}
}

使用

import 'package:flutter/material.dart';
import 'package:flutter_xy/widgets/xy_app_bar.dart';
import 'package:flutter_xy/xydemo/darg/drag_bottom_sheet_widget.dart';class DragBottomSheetPage extends StatefulWidget {const DragBottomSheetPage({super.key});@overrideState<DragBottomSheetPage> createState() => _DragBottomSheetPageState();
}class _DragBottomSheetPageState extends State<DragBottomSheetPage> {final GlobalKey<DragBottomSheetWidgetState> bottomSheetKey =GlobalKey<DragBottomSheetWidgetState>();bool isExpand = false;@overrideWidget build(BuildContext context) {return Scaffold(backgroundColor: Colors.deepPurple.withAlpha(50),appBar: XYAppBar(title: "底部弹出布局",backgroundColor: Colors.transparent,titleColor: Colors.white,onBack: () {Navigator.pop(context);},),body: Stack(children: [Positioned(top: 0,child: Column(mainAxisSize: MainAxisSize.max,children: [InkWell(onTap: () {if (isExpand) {bottomSheetKey.currentState?.hide();} else {bottomSheetKey.currentState?.show();}},child: Container(width: MediaQuery.of(context).size.width - 60,alignment: Alignment.center,height: 50,margin: const EdgeInsets.symmetric(horizontal: 30),decoration: BoxDecoration(borderRadius: BorderRadius.circular(32),color: Colors.deepPurple,),child: Text(isExpand ? "收起" : "弹出",style: const TextStyle(fontSize: 16,fontWeight: FontWeight.w600,color: Colors.white,),),),),const SizedBox(height: 20),],)),Positioned(child: DragBottomSheetWidget(key: bottomSheetKey,onStateChange: (isExpand) {setState(() {this.isExpand = isExpand;});},builder:(BuildContext context, ScrollController scrollController) {return Container(alignment: Alignment.topLeft,child: Stack(children: [Container(height: 50,decoration: const BoxDecoration(borderRadius: BorderRadius.only(topLeft: Radius.circular(16),topRight: Radius.circular(16)),color: Colors.yellow,),),Expanded(child: Container(margin: const EdgeInsets.only(top: 50),child: ListView.builder(itemCount: 500,controller: scrollController,itemBuilder: (context, index) {return index % 2 == 0? Container(height: 100,width: MediaQuery.of(context).size.width,color: Colors.red,): Container(height: 100,width: MediaQuery.of(context).size.width,color: Colors.blue,);},),),),],),);},),),],),);}
}

完整代码见:https://github.com/yixiaolunhui/flutter_xy

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

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

相关文章

机器学习-04-分类算法-04-支持向量机SVM

总结 本系列是机器学习课程的系列课程&#xff0c;主要介绍机器学习中分类算法&#xff0c;本篇为分类算法与SVM算法部分。 本门课程的目标 完成一个特定行业的算法应用全过程&#xff1a; 懂业务会选择合适的算法数据处理算法训练算法调优算法融合 算法评估持续调优工程化…

HTML5球体下落粒子爆炸特效

HTML5球体下落粒子爆炸特效&#xff0c;源码由HTMLCSSJS组成&#xff0c;双击html文件可以本地运行效果&#xff0c;也可以上传到服务器里面 下载地址 HTML5球体下落粒子爆炸特效

阿里云2核4G4M轻量应用服务器价格165元一年

阿里云优惠活动&#xff0c;2核4G4M轻量应用服务器价格165元一年&#xff0c;4Mbps带宽下载速度峰值可达512KB/秒&#xff0c;系统盘是60GB高效云盘&#xff0c;不限制月流量&#xff0c;2核2G3M带宽轻量服务器一年87元12个月&#xff0c;在阿里云CLUB中心查看 aliyun.club 当前…

数据结构—稀疏多项式相加

利用链表实现两个稀疏多项式相加。 代码 #include <iostream> using namespace std;// 定义多项式项结构体 typedef struct {int x; // 系数int y; // 指数 } Elemtype;// 定义链表节点结构体 typedef struct Node {Elemtype data;struct Node* next; } *LinkList, N…

数据结构中单向链表(无头)的学习

一.数据结构 1.定义 一组用来保存一种或者多种特定关系的数据的集合&#xff08;组织和存储数据&#xff09; 程序的设计&#xff1a;将现实中大量而复杂的问题以特定的数据类型和特定的存储结构存储在内存中&#xff0c; 并在此基础上实现某个特定的功能的操…

VSCode + PicGo + Github 实现markdown图床管理

目录 PicGo客户端VSvode插件 PicGo客户端 PicGo 是一个图片上传管理工具 官网&#xff1a;https://molunerfinn.com/PicGo/ github图传使用说明&#xff1a;https://picgo.github.io/PicGo-Doc/zh/guide/config.html#GitHub图床 步骤&#xff1a; 1、创建一个github公开仓库…

小程序搜索排名优化二三事

小程序的优化主要是排名优化和性能优化两个版块。性能优化这方面主要靠开发者自己完善&#xff0c;我们团队提供的服务就是把产品的排名打上去&#xff0c;获得更多的自然流量&#xff0c;实现盈利。 如何提升小程序的搜索排名主要从如下几个方面出发&#xff1a; 首先要知道…

2023新版mapinfo美化电子地图 新版2013Arcgis shp电子地图 下载

2023新版MapInfo和电子地图美化&#xff0c;以及2013版ArcGIS的SHP电子地图设计&#xff0c;是地理信息系统&#xff08;GIS&#xff09;领域中的两个重要话题。下面将分别对这两个主题进行描述。 样图&#xff1a; 链接&#xff1a;https://pan.baidu.com/s/1WB4AGsycyBGagVq5…

文心一言赋能问卷生成,打造高效问卷调研工具

当前&#xff0c;各种大语言模型&#xff08;LLM&#xff0c;Large Language Model&#xff09;井喷式发展&#xff0c;基于LLM的应用也不断涌现。但是&#xff0c;当开发者基于LLM开发下游应用时&#xff0c;LLM直接生成的结果在格式、内容等方面都存在许多不确定因素&#xf…

【数据结构和算法初阶(C语言)】二叉树的顺序结构--堆的实现/堆排序/topk问题详解---二叉树学习日记②

目录 ​编辑 1.二叉树的顺序结构及实现 1.1 二叉树的顺序结构 2 堆的概念及结构 3 堆的实现 3.1堆的代码定义 3.2堆插入数据 3.3打印堆数据 3.4堆的数据的删除 3.5获取根部数据 3.6判断堆是否为空 3.7 堆的销毁 4.建堆以及堆排序 4.1 升序建大堆&#xff0c;降序建小堆 4.2堆…

【C语言步行梯】一级指针、二级指针、指针数组等 | 指针详谈

&#x1f3af;每日努力一点点&#xff0c;技术进步看得见 &#x1f3e0;专栏介绍&#xff1a;【C语言步行梯】专栏用于介绍C语言相关内容&#xff0c;每篇文章将通过图片代码片段网络相关题目的方式编写&#xff0c;欢迎订阅~~ 文章目录 什么是指针&#xff1f;指针的大小指针类…

SpringMVC | SpringMVC中的“JSON数据交互“ 和“RESTful支持“

目录: 1.JSON 数据交互1.1 JSON概述1.2 JSON的“数据结构”对象结构数组结构 1.3 JSON的“数据转换” (JSON交互) 作者简介 &#xff1a;一只大皮卡丘&#xff0c;计算机专业学生&#xff0c;正在努力学习、努力敲代码中! 让我们一起继续努力学习&#xff01; 该文章参考学习教…

HUAWEI Pocket 2外屏实时查看App动态,小小窗口大便捷

当我们点外卖、等候飞机时&#xff0c;不少人习惯频繁点亮手机查看外卖配送进度、值机时间。 这时候&#xff0c;手机亮屏、解锁、打开对应App查看状态对于我们来说就显得非常繁琐。而华为Pocket 2结合HarmonyOS 4系统的实况窗功能&#xff0c;与常显外屏的搭配使用&#xff0…

微服务技术栈SpringCloud+RabbitMQ+Docker+Redis+搜索+分布式(五):分布式搜索 ES-下

文章目录 一、数据聚合1.1 聚合种类1.2 DSL实现聚合1.3 RestAPI实现聚合1.4 演示&#xff1a;多条件聚合 二、自动补全2.1 拼音分词器2.2 自定义分词器2.3 DSL自动补全查询2.5 实现酒店搜索框自动补全2.5.1 修改酒店索引库数据结构2.5.2 RestAPI实现自动补全查询2.5.3 实战 三、…

CSS案例-2.简单版侧边栏练习

效果 知识点 标签显示模式 块级元素 block-level 常见元素:<h1>~<h6>、<p>、<div>、<ul>、<ol>、<li>等。 特点: 独占一行长度、宽度、边距都可以控制宽度默认是容器(父级宽度)的100%是一个容器及盒子,里面可以放行内或者…

Docker部署TeamCity来完成内部CI、CD流程

使用TeamCity来完成内部CI、CD流程 本篇教程主要讲解基于容器服务搭建TeamCity服务&#xff0c;并且完成内部项目的CI流程配置。至于完整的DevOps&#xff0c;我们后续独立探讨。 一个简单的CI、CD流程 以下分享一个简单的CI、CD流程&#xff08;仅供参考&#xff09;&#…

SCI一区 | Matlab实现RIME-TCN-BiGRU-Attention霜冰算法优化时间卷积双向门控循环单元融合注意力机制多变量时间序列预测

SCI一区 | Matlab实现RIME-TCN-BiGRU-Attention霜冰算法优化时间卷积双向门控循环单元融合注意力机制多变量时间序列预测 目录 SCI一区 | Matlab实现RIME-TCN-BiGRU-Attention霜冰算法优化时间卷积双向门控循环单元融合注意力机制多变量时间序列预测预测效果基本介绍模型描述程…

DEYOv2: Rank Feature with Greedy Matchingfor End-to-End Object Detection

摘要 与前代类似&#xff0c; DEYOv2 采用渐进式推理方法 来加速模型训练并提高性能。该研究深入探讨了一对一匹配在优化器中的局限性&#xff0c;并提出了有效解决该问题的解决方案&#xff0c;如Rank 特征和贪婪匹配 。这种方法使DEYOv2的第三阶段能够最大限度地从第一和第二…

Pytorch环境下基于Transformer模型的滚动轴承故障诊断

注意力机制是深度学习中的重要技术之一&#xff0c;正日益受到重视关注。注意力机制作为一种信息贡献筛选的方法被提出&#xff0c;它可以帮助神经网络更多地关注与任务相关的特征&#xff0c;从而减少对任务贡献较小信息的影响。因此&#xff0c;利用注意机制可以提高神经网络…

ArcGIS巧思制作3D景观地图

John Nelson 又制作了一个制图教程视频,我原以为只是一个简单的局部场景DEM夸张实现的3D地图。 不过细看以后…… 还就是比较简单的3D场景地图,操作不难,但是 John Nelson 就是天才。 为什么? 他使用 ArcGIS Pro,在普通的3D地图中,不仅仅是图层混合制作地形效果,还巧妙的…