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.rhkb.cn/news/279772.html

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

相关文章

行业回暖?这个行业岗位需求飙升6倍!程序员们提前恭喜了!

前言 随着今年史上最长春节假期正式收官&#xff0c;各行各业相继进入开工节奏&#xff0c;就业市场开启持续升温模式。 今年开工首周&#xff0c;人才需求增长明显&#xff0c;求职者活跃度大大增多&#xff0c;就业市场进入了繁忙有序的节奏&#xff0c;呈现出春招市场的勃…

CI/CD实战-git工具使用 1

版本控制系统 本地版本控制系统 集中化的版本控制系统 分布式版本控制系统 git官网文档&#xff1a;https://git-scm.com/book/zh/v2 Git 有三种状态&#xff1a;已提交&#xff08;committed&#xff09;、已修改&#xff08;modified&#xff09; 和 已暂存&#xff08;sta…

查找众数及中位数 - 华为OD统一考试(C卷)

OD统一考试(C卷) 分值: 100分 题解: Java / Python / C++ 题目描述 众数是指一组数据中出现次数量多的那个数,众数可以是多个。 中位数只是指把一组数据从小到大排列,最中间的那个数,如果这组数据的个数是奇数,那最中间那个就是中位数,如果这组数据的个数为偶数,那…

harmonyOS简介及背景

harmonyOS的场景模式18n: 1&#xff08;入口手机&#xff09;8&#xff08;电脑、VR、手环、iPad、智慧屏、&#xff09;–wifi—n(车载、智能家居等所有)harmonyOS不需要考虑软硬件的差异&#xff0c;是一个兼容N种的超级终端harmonyOS干了两件事&#xff1a; &#xff08;1&a…

没有经验就开通抖店,你会遇到以下这些问题!2024抖店教程(新版)

我是王路飞。 没有经验的人去做抖店的话&#xff0c;都会遇到哪些问题呢&#xff1f; 大概率逃脱不开这些问题&#xff1a; 店铺的类型怎么选&#xff1f; 店铺的流量从哪来&#xff1f; 没有货源但又担心做无货源模式会被平台判定违规&#xff1b; 怎么才能快速把店铺做…

pytorch 入门基础知识二(Pytorch 02)

一 微积分 1.1 导数和微分 微分就是求导&#xff1a; %matplotlib inline import numpy as np from matplotlib_inline import backend_inline from d2l import torch as d2l def f(x):return 3 * x ** 2 - 4 * x 定义&#xff1a; 然后求 f(x) 在 x 1 时的导数&#xff…

深入理解Ubuntu22:探索Linux操作系统的功能与应用

一、linux &#xff08;一&#xff09;、安装 1、电脑可以安装双系统&#xff0c;即在一套硬件上只能同时运行一个操作系统&#xff0c;例&#xff1a;C盘安装win&#xff0c;D盘安装linux。 2、虚拟机 虚拟机需要硬件支持&#xff0c;并需开启VT-x. 如&#xff1a;Virtual…

PLM系统实施的六大难点及其解决方法

实施PLM系统是企业实现产品全生命周期管理的重要举措&#xff0c;但在实施过程中往往会面临一些难点。本文将探讨实施PLM系统的主要难点及其解决方法。 首先&#xff0c;数据迁移和整合是实施PLM系统的一个关键挑战。企业可能拥有大量的现有数据&#xff0c;包括设计文件、工艺…

幼儿教育管理系统|基于jsp 技术+ Mysql+Java的幼儿教育管理系统设计与实现(可运行源码+数据库+设计文档)

推荐阅读100套最新项目 最新ssmjava项目文档视频演示可运行源码分享 最新jspjava项目文档视频演示可运行源码分享 最新Spring Boot项目文档视频演示可运行源码分享 2024年56套包含java&#xff0c;ssm&#xff0c;springboot的平台设计与实现项目系统开发资源&#xff08;可…

HANA VIEW 用 ABAP 创建CDS VIEW,在生成ODATA

这里我们做ADT来创建 场景介绍:把hana中的一个底表,创建成ABAP的 CDS VIEW ,在把CDS VIEW 生成 OData 服务。 一、创建CDS Table Function 红框内根据自身情况填写 选择 Define Table Function with Parameters 创建 Data Definition 完整代码,定义 结构 , 也可以定义参…

力扣Lc18--- 168. Excel表列名称(java版)-2024年3月19日

1.题目描述 2.知识点 因为是输入字符 然后显示数字。 就类似2进制10代表2&#xff0c;110代表4&#xff0c;用某进制次幂的方式返回最后的数字结果。 3.代码实现 class Solution {public int titleToNumber(String columnTitle) {int sum0;for(int i0;i<columnTitle.len…

python网络爬虫实战教学——urllib的使用(1)

文章目录 专栏导读1、前言2、urllib的使用3、发送请求3.1 urlopen3.2 request 专栏导读 ✍ 作者简介&#xff1a;i阿极&#xff0c;CSDN 数据分析领域优质创作者&#xff0c;专注于分享python数据分析领域知识。 ✍ 本文录入于《python网络爬虫实战教学》&#xff0c;本专栏针对…

C#对ListBox控件中的数据进行的操作

目录 1.添加数据&#xff1a; 2.删除数据&#xff1a; 3.清空数据&#xff1a; 4.选择项&#xff1a; 5.排序&#xff1a; 6.获取选中的项&#xff1a; 7.获取ListBox中的所有项&#xff1a; 8.综合示例 C#中对ListBox控件中的数据进行的操作主要包括添加、删除、清空、…

关于小仙炖燕窝的崛起!

产品策略 爆火逻辑 1. 超级品类&#xff1a;对传统的升级 干燕窝&#xff1a;选&#xff1f;炖&#xff1f;吃&#xff1f; &#xff08;口感差&#xff09;即食燕窝&#xff1a;新鲜&#xff1f;营养&#xff1f;&#xff08;营养保障&#xff09;鲜炖燕窝&#xff1a;保质期、…

【鸿蒙HarmonyOS开发笔记】应用数据持久化之通过关系型数据库实现数据持久化

概述 关系型数据库&#xff08;Relational Database&#xff0c;RDB&#xff09;是一种基于关系模型来管理数据的数据库。关系型数据库基于SQLite组件提供了一套完整的对本地数据库进行管理的机制&#xff0c;对外提供了一系列的增、删、改、查等接口&#xff0c;也可以直接运…

18个惊艳的可视化大屏(第28辑):房产楼盘领域

在房产楼盘领域&#xff0c;可视化的大屏可以提供以下九大价值&#xff1a; 展示楼盘信息 可视化的大屏可以用于展示楼盘的基本信息&#xff0c;包括楼盘名称、位置、户型、价格、面积等&#xff0c;帮助潜在客户快速了解楼盘的特点和优势。 展示楼盘效果图 通过大屏展示楼盘…

load函数无法正常加载CUDA扩展的问题(程序在某一行突然卡死,也不报错,也不停止运行就可以考虑这个原因)

背景&#xff1a;在服务器上跑代码的时候&#xff0c;有时候会遇到程序在某一行代码卡死(阻塞)&#xff0c;既不报错&#xff0c;也不停止运行&#xff0c;就堵在那里。 此时就可以考虑是代码在哪里碰到了load函数&#xff0c;load函数无法正常加载CUDA扩展的问题。 下面以碰到…

MFC界面美化第三篇----自绘按钮(重绘按钮)

1.前言 最近发现读者对我的mfc美化的专栏比较感兴趣&#xff0c;因此在这里进行续写&#xff0c;这里我会计划写几个连续的篇章&#xff0c;包括对MFC按钮的美化&#xff0c;菜单栏的美化&#xff0c;标题栏的美化&#xff0c;list列表的美化&#xff0c;直到最后形成一个完整…

S2-066漏洞分析与复现(CVE-2023-50164)

Foreword 自struts2官方纰漏S2-066漏洞已经有一段时间&#xff0c;期间断断续续地写&#xff0c;直到最近才完成&#xff0c;o(╥﹏╥)o。羞愧地回顾一下官方通告&#xff1a; 2023.12.9发布&#xff0c;编号CVE-2023-50164&#xff0c;主要影响版本是 2.5.0-2.5.32 以及 6.0…

[薅羊毛活动]体验AI编码和开盲盒

​​​​​​​通义灵码 体验 AI 编码&#xff0c;开 AI 盲盒 上面是我的邀请码,直接点击 活动说明 【活动玩法一】“体验AI编码、领取AI盲盒”活动玩法 玩法简述&#xff1a;用户进入活动页面后&#xff0c;随机参与或体验活动页面中通义灵码的任一场景&#xff0c;即可获…