Flutter实现StackView
1.让界面之间可以嵌套且执行动画。
2.界面的添加遵循先进后出原则。
3.需要使用AnimateView,请看我上一篇博客。
演示:

代码:
Stack:
import 'package:flutter/cupertino.dart';///栈,先进后出
class KqWidgetStack {final List<Widget> _stack = [];///入栈push(Widget obj) {_stack.add(obj);}///出栈Widget? pop() {if (_stack.isEmpty) {return null;} else {return _stack.removeLast();}}///栈长度length() {return _stack.length;}///清除栈clear() {_stack.clear();}
}
 
StackView:
import 'package:flutter/cupertino.dart';
import 'package:kq_flutter_widgets/widgets/animate/animate_view.dart';
import 'package:kq_flutter_widgets/widgets/stackview/stack.dart';class StackView extends StatefulWidget {///初始显示的界面final Widget initChild;///state回调。获取state后方便后续界面操作。final void Function(StackViewState state)? stateCallback;const StackView({super.key,required this.initChild,this.stateCallback,});@overrideState<StatefulWidget> createState() => StackViewState();
}class StackViewState extends State<StackView> {final KqWidgetStack _stack = KqWidgetStack();bool _isOpen = true;Widget? _previousWidget;Widget? _currentWidget;@overridevoid initState() {super.initState();_currentWidget = widget.initChild;widget.stateCallback?.call(this);}@overrideWidget build(BuildContext context) {if (_currentWidget == null) {return Container();} else if (_previousWidget == null) {return _isOpen? AnimateView(animate: TranslationAnimate(angle: TranslationAnimateDirection.bottomToTop.angle,type: TranslationAnimateType.translateIn),child: _currentWidget!,): AnimateView(animate: TranslationAnimate(angle: TranslationAnimateDirection.topToBottom.angle,type: TranslationAnimateType.translateOut),child: _currentWidget!,);} else {return _isOpen? Stack(children: [AnimateView(animate: TranslationAnimate(angle: TranslationAnimateDirection.bottomToTop.angle,type: TranslationAnimateType.translateOut),isNeedFlashEveryTime: true,child: _previousWidget!,),AnimateView(animate: TranslationAnimate(angle: TranslationAnimateDirection.bottomToTop.angle,type: TranslationAnimateType.translateIn),isNeedFlashEveryTime: true,child: _currentWidget!,),],): Stack(children: [AnimateView(animate: TranslationAnimate(angle: TranslationAnimateDirection.topToBottom.angle,type: TranslationAnimateType.translateOut),isNeedFlashEveryTime: true,child: _previousWidget!,),AnimateView(animate: TranslationAnimate(angle: TranslationAnimateDirection.topToBottom.angle,type: TranslationAnimateType.translateIn),isNeedFlashEveryTime: true,child: _currentWidget!,),],);}}addWidget(Widget page) {_isOpen = true;_previousWidget = _currentWidget;_currentWidget = page;if (_previousWidget != null) {_stack.push(_previousWidget!);}print("stack size=${_stack.length()}");setState(() {});}///回退,返回上一个界面。///[bool] 返回true表示成功返回上一级,///返回false表示返回失败,已是最后一个界面,不可继续返回。bool back() {_isOpen = false;_previousWidget = _currentWidget;_currentWidget = _stack.pop();print("stack size=${_stack.length()}");setState(() {});if (_stack.length() > 1) {return true;} else {return false;}}@overridevoid dispose() {super.dispose();_stack.clear();}
}
 
demo:
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:kq_flutter_widgets/widgets/button/kq_small_button.dart';
import 'package:kq_flutter_widgets/widgets/stackview/stack_view.dart';
import 'package:kq_flutter_widgets/widgets/titleBar/kq_title_bar.dart';class StackViewDemo extends StatefulWidget {const StackViewDemo({super.key});@overrideState<StatefulWidget> createState() => StackViewDemoState();
}class StackViewDemoState extends State<StackViewDemo> {StackViewState? state;@overrideWidget build(BuildContext context) {return Scaffold(appBar: KqHeadBar(headTitle: 'StackView演示',back: () {Get.back();},),body: StackView(initChild: Column(children: [const Text("我是首页"),KqSmallButton(title: "打开新页面",onTap: (disabled) {state?.addWidget(TestPage1(state: state!));},),Expanded(child: Container(color: Colors.purple,)),],),stateCallback: (StackViewState state) {this.state = state;},),);}
}class TestPage1 extends StatelessWidget {final StackViewState state;const TestPage1({super.key, required this.state});@overrideWidget build(BuildContext context) {return Column(children: [const Text("我是TestPage1"),KqSmallButton(title: "返回",onTap: (disabled) {state.back();},),KqSmallButton(title: "打开新页面",onTap: (disabled) {state.addWidget(TestPage2(state: state));},),Expanded(child: Container(color: Colors.amber,)),],);}
}class TestPage2 extends StatelessWidget {final StackViewState state;const TestPage2({super.key, required this.state});@overrideWidget build(BuildContext context) {return Column(children: [const Text("我是TestPage2"),KqSmallButton(title: "返回",onTap: (disabled) {state.back();},),KqSmallButton(title: "打开新页面",onTap: (disabled) {state.addWidget(TestPage3(state: state));},),Expanded(child: Container(color: Colors.cyan,)),],);}
}class TestPage3 extends StatelessWidget {final StackViewState state;const TestPage3({super.key, required this.state});@overrideWidget build(BuildContext context) {return Column(children: [const Text("我是TestPage3"),KqSmallButton(title: "返回",onTap: (disabled) {state.back();},),Expanded(child: Container(color: Colors.blueAccent,)),],);}
}
 
相关文章:
Flutter实现StackView
1.让界面之间可以嵌套且执行动画。 2.界面的添加遵循先进后出原则。 3.需要使用AnimateView,请看我上一篇博客。 演示: 代码: Stack: import package:flutter/cupertino.dart;///栈,先进后出 class KqWidgetStack {final Lis…...
c++ future与promise
C11 标准中 头文件中包含了以下几个类和函数: Providers 类:std::promise, std::package_taskFutures 类:std::future, shared_future.Providers 函数:std::async()其他类型:std::future_error, std::future_errc, st…...
在x86机器上的Docker运行arm64容器
1. 引言 工作中常用电脑主机CPU为x86架构,有时由于产品需要,我们需要编译aarch64架构的SDK或者应用程序供使用或者测试。 一种比较快捷的方式是使用aarch64的CPU构建相应操作系统,实现真机运行。但在无arm架构CPU环境下,我们可否…...
centos7删除乱码文件
centos7删除乱码文件1. 小白教程,一看就会,一做就成。 1.解释 当文件名为乱码的时候,无法通过键盘输入文件名,所以在终端下就不能直接利用rm,mv等命令管理文件了。 但是每个文件都有一个i节点号,可以通过…...
uni-app里使用webscoket
实现思路和vue中是一样的。如果想看思路可以看这篇文章:websocket 直接上可以运行的代码: 一、后端nodeJS代码: 1、新建项目文件夹 2、初始化项目: npm init -y 3、项目里安装ws npm i ws --save 4、nodeJS代码࿱…...
jdk17+springboot使用webservice,踩坑记录
这几天wms对接lbpm系统,给我的接口是webservice的,老实说,这个技术很早,奈何人家只支持这个。 环境说明:JDK17 springboot2.6.6。网上很多教程是基于jdk8的,所以很多在17上面跑不起来。折腾两天,…...
计算机网络文件拆分—视频流加载、断点续传
视频流加载 视频流加载的原理是通过网络传输和播放器解码来实现的。 首先,视频文件会被分成一系列小的数据包,通常是以流的形式传输,这些数据包通过网络传输到用户设备。在传输过程中,可以采用各种协议,如HTTP、RTSP…...
JVM 给对象分配内存空间
指针碰撞空闲列表TLAB 为对象分配空间的任务实际上便等同于把一块确定大小的内存块从Java堆中划分出来。 指针碰撞:(Bump The Pointer) 堆的内存是绝对规整的,内存主要分为两部分,所有使用过的内存被放在一边&#x…...
Excel·VBA二维数组组合函数、组合求和
目录 1,二维数组组合函数举例 2,组合求和 之前的文章《ExcelVBA数组组合函数、组合求和》和《ExcelVBA数组排列函数》,都是针对一维数组的组合和排列 二维数组组合:对一个m行*n列的二维数组,每行抽取1个元素进行组合&a…...
调用自实现MyGetProcAddress获得CreateFileA函数并调用创建写入文件
写文件如下 #include <iostream> #include <Windows.h>typedef HANDLE(WINAPI* CreateFileAFunc)(LPCSTR, DWORD, DWORD, LPSECURITY_ATTRIBUTES, DWORD, DWORD, HANDLE);DWORD MyGetProcAddress(_In_ HMODULE hModule,_In_ LPCSTR lpProcName ){PIMAGE_DOS_HEADE…...
Leetcode 191.位1的个数
编写一个函数,输入是一个无符号整数(以二进制串的形式),返回其二进制表达式中数字位数为 1 的个数(也被称为汉明重量)。 提示: 请注意,在某些语言(如 Java)中…...
安防监控视频平台EasyCVR视频汇聚平台调用接口出现跨域现象的问题解决方案
视频监控汇聚EasyCVR可拓展性强、视频能力灵活、部署轻快,可支持的主流标准协议有GB28181、RTSP/Onvif、RTMP等,以及厂家私有协议与SDK接入,包括海康Ehome、海大宇等设备的SDK等,能对外分发RTSP、RTMP、FLV、HLS、WebRTC等格式的视…...
Python中的一些常用操作
文章目录 一. Python操作之-- 使用Python 提取PDF文件中的表格数据!二:三: Python中的 staticmethodclassmethod方法四: 反斜杠 \五: 终端的解释器提示符号修改六: python使用json.dumps输出中文七…...
go语言调用python脚本
文章目录 代码gopython 在 go语言中调用 python 程序,你可能会用到 代码 亲测 go 测试 go 文件 func TestR(t *testing.T) {// 设置要执行的Python脚本和参数scriptPath : "../nansen.py"arg1 : "nansen"// 执行Python脚本cmd : exec.Comm…...
2.3 【MySQL】命令行和配置文件中启动选项的区别
在命令行上指定的绝大部分启动选项都可以放到配置文件中,但是有一些选项是专门为命令行设计的,比方说defaults-extra-file 、 defaults-file 这样的选项本身就是为了指定配置文件路径的,再放在配置文件中使用就没啥意义了。 如果同一个启动选…...
外部库/lib/maven依赖项 三者关系
外部库(存放项目初始配置的jar包)(它的文件夹里并没有包含lib文件夹的引的外部的依赖的jar包) lib(存放外部导入到项目的依赖的jar包) maven依赖项(管理项目所有的jar包依赖) 三者存放jar包的关系 项目所依赖的全部的jar包 maven依赖项的jar包 外部库中的jar包 lib中的…...
在线制作作息时间表
时光荏苒,岁月如梭,人们描述时光易逝的句子,多如星河。 一寸光阴一寸金,寸金难买寸光阴。 人生就是一段时间而已,所以我明白了一个道理 人生之中最大的浪费就是时间的浪费 因此我想我们教给我们孩子重要的一课应该也是…...
他们朝我扔泥巴(scratch)
前言 纯~~~属~~~虚~~~构~~~(同学看完短视频要我做,蟹蟹你) 用scratch做的,幼稚得嘞( ̄_ ̄|||)呵呵(强颜欢笑) 完成视频 视频试了好久,就是传不上来,私信我加我…...
docker部署前端项目保姆级教程
本地启动docker(有不会启动的吗?下载docker(小海豚)双击起来就行) 准备阿里云账号(免费) 没有就去注册一个,记住密码后面要用到 官网地址:阿里云登录 - 欢迎登录阿里云…...
《C和指针》笔记13: static关键字总结
这里对static关键字做一下总结,可以回顾一下前面两篇博客的文章。 《C和指针》笔记11: external和internal链接属性 《C和指针》笔记12: 存储类型(自动变量、静态变量和寄存器变量) 当它用于函数定义时,或用于代码块之外的变量声…...
Xshell远程连接Kali(默认 | 私钥)Note版
前言:xshell远程连接,私钥连接和常规默认连接 任务一 开启ssh服务 service ssh status //查看ssh服务状态 service ssh start //开启ssh服务 update-rc.d ssh enable //开启自启动ssh服务 任务二 修改配置文件 vi /etc/ssh/ssh_config //第一…...
PPT|230页| 制造集团企业供应链端到端的数字化解决方案:从需求到结算的全链路业务闭环构建
制造业采购供应链管理是企业运营的核心环节,供应链协同管理在供应链上下游企业之间建立紧密的合作关系,通过信息共享、资源整合、业务协同等方式,实现供应链的全面管理和优化,提高供应链的效率和透明度,降低供应链的成…...
LeetCode - 394. 字符串解码
题目 394. 字符串解码 - 力扣(LeetCode) 思路 使用两个栈:一个存储重复次数,一个存储字符串 遍历输入字符串: 数字处理:遇到数字时,累积计算重复次数左括号处理:保存当前状态&a…...
1688商品列表API与其他数据源的对接思路
将1688商品列表API与其他数据源对接时,需结合业务场景设计数据流转链路,重点关注数据格式兼容性、接口调用频率控制及数据一致性维护。以下是具体对接思路及关键技术点: 一、核心对接场景与目标 商品数据同步 场景:将1688商品信息…...
最新SpringBoot+SpringCloud+Nacos微服务框架分享
文章目录 前言一、服务规划二、架构核心1.cloud的pom2.gateway的异常handler3.gateway的filter4、admin的pom5、admin的登录核心 三、code-helper分享总结 前言 最近有个活蛮赶的,根据Excel列的需求预估的工时直接打骨折,不要问我为什么,主要…...
前端开发面试题总结-JavaScript篇(一)
文章目录 JavaScript高频问答一、作用域与闭包1.什么是闭包(Closure)?闭包有什么应用场景和潜在问题?2.解释 JavaScript 的作用域链(Scope Chain) 二、原型与继承3.原型链是什么?如何实现继承&a…...
css3笔记 (1) 自用
outline: none 用于移除元素获得焦点时默认的轮廓线 broder:0 用于移除边框 font-size:0 用于设置字体不显示 list-style: none 消除<li> 标签默认样式 margin: xx auto 版心居中 width:100% 通栏 vertical-align 作用于行内元素 / 表格单元格ÿ…...
OpenLayers 分屏对比(地图联动)
注:当前使用的是 ol 5.3.0 版本,天地图使用的key请到天地图官网申请,并替换为自己的key 地图分屏对比在WebGIS开发中是很常见的功能,和卷帘图层不一样的是,分屏对比是在各个地图中添加相同或者不同的图层进行对比查看。…...
Spring AI与Spring Modulith核心技术解析
Spring AI核心架构解析 Spring AI(https://spring.io/projects/spring-ai)作为Spring生态中的AI集成框架,其核心设计理念是通过模块化架构降低AI应用的开发复杂度。与Python生态中的LangChain/LlamaIndex等工具类似,但特别为多语…...
Python基于历史模拟方法实现投资组合风险管理的VaR与ES模型项目实战
说明:这是一个机器学习实战项目(附带数据代码文档),如需数据代码文档可以直接到文章最后关注获取。 1.项目背景 在金融市场日益复杂和波动加剧的背景下,风险管理成为金融机构和个人投资者关注的核心议题之一。VaR&…...
