flutter显示出底部控件的引导页
需求:同一个页面的两个不同的入口,同一个控件的位置有变化,显示引导页时对应这个控件的引导内容的位置也需要改变;同时半透明底部显示出真实的页面内容。
这样的需要如果切图然后再往页面上贴位置无法精确的对准。
思路:先绘制一层半透明遮罩覆盖页面,在需要显示的控件位置绘制为全透明,然后再将引导内容绘制在遮罩上面(共有三层,真实页面、透明遮罩。控件对应的那些说明内容),获取控件的位置确定在哪里全透明。
入口一进入时:

入口二进入时:

import 'package:common/sp_util.dart';
import 'package:jade/configs/CommonConfig.dart';
import 'package:jade/configs/PathConfig.dart';
import 'package:jade/utils/JadeColors.dart';
import 'package/jade/utils/Utils.dart';
import 'package:util/navigator_util.dart';
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
/*
* 引导页
* */
class SharedPurchaseGuidePage extends StatelessWidget {final double width;final double height;final Offset offset;const SharedPurchaseGuidePage({this.width,this.height,this.offset});Widget build(BuildContext context) {return WillPopScope(child: Stack(children: [CustomPaint(size: Size(Utils().screenWidth(context), Utils().screenHeight(context)), // 自定义Widget的大小painter: MyCustomPainter(width,height,offset),),Positioned(left: offset.dx + width,top: offset.dy,child: _leftView(context))],),onWillPop: () async => false,);}_leftView(context){return Container(width: Utils().screenWidth(context) * 0.68,height: 210.w,padding: EdgeInsets.symmetric(vertical: 28.w),decoration: BoxDecoration(image: DecorationImage(image: AssetImage(PathConfig.imageSharedPurchaseGuideBg),fit: BoxFit.fill)),child: Column(crossAxisAlignment: CrossAxisAlignment.end,children: [Row(mainAxisAlignment: MainAxisAlignment.end,children: [Text('点击了解共享购',style: TextStyle(color: Colors.white,fontSize: 28.sp,fontWeight: FontWeight.w600)),SizedBox(width: 54.w),GestureDetector(child: Container(width: 100.w,height: 40.w,alignment: Alignment.center,margin: EdgeInsets.only(right: 20.w),decoration: BoxDecoration(color: Colors.white,borderRadius: BorderRadius.circular(20),),child: Text('知道了',style: TextStyle(color: JadeColors.blue,fontSize: 22.sp,fontWeight: FontWeight.w600),),),onTap: (){SpUtil.putBool(CommonConfig.havePostDetailSharedPurchaseGuide, true);NavigatorUtil.pop();},)],),Container(margin: EdgeInsets.only(right: 20.w,top: 26.w),child: Text('为促进交易,本版块加入了独特的共\n享购功能,与传统的团购与拼单很不\n一样,欢迎体验!',style: TextStyle(color: Colors.white,fontSize: 22.sp)))],),);}
}class MyCustomPainter extends CustomPainter {final double width;final double height;final Offset offset;const MyCustomPainter(this.width,this.height,this.offset);void paint(Canvas canvas, Size size) {//背景Paint backgroundPaint = Paint()..color = Colors.black45..style = PaintingStyle.fill;//添加背景一个路径Path path = Path()..addRect(Rect.fromLTWH(0, 0, size.width, size.height));//留白的圆角矩形路径Path holePath = Path()// ..addRect(Rect.fromLTWH(offset.dx, offset.dy, width, height));..addRRect(RRect.fromRectAndRadius(Rect.fromLTWH(offset.dx-5, offset.dy, width+5, height), Radius.circular(5)));Path combinedPath = Path.combine(PathOperation.difference, path, holePath);canvas.drawPath(combinedPath, backgroundPaint);}bool shouldRepaint(covariant CustomPainter oldDelegate) {return false; // 不需要重绘,因为我们只是绘制一次,并没有动画或状态更改}
}
GlobalKey _sharedPurchaseKey = new GlobalKey();
//需要全透明的控件
Row(key: _sharedPurchaseKey,children: [Text(S.current.sharedPurchase,style: TextStyle(color: JadeColors.blue,fontSize: 24.sp,fontWeight: FontWeight.bold)),GestureDetector(child: Container(color: Colors.transparent,padding: EdgeInsets.all(4),child: Image.asset(PathConfig.iconQuestion,width: 34.w,height: 34.w),),onTap: (){NavigatorUtil.push(SharedPurchaseDesc());},),],),//获取共享购文字加问号的坐标,跳转(这个方法需要在页面加载完成后调用)_getOffset() {if(_sharedPurchaseKey.currentContext != null){_sharedPurchaseWidth = _sharedPurchaseKey.currentContext.size.width;_sharedPurchaseHeight = _sharedPurchaseKey.currentContext.size.height;_offset = WidgetUtil.getWidgetLocalToGlobal(_sharedPurchaseKey.currentContext);bool sharedPurchaseGuide = SpUtil.getBool(CommonConfig.havePostDetailSharedPurchaseGuide,defValue: false);if(!sharedPurchaseGuide){//跳转一个透明页面NavigatorUtil.pushTransparentRoute(SharedPurchaseGuidePage(width: _sharedPurchaseWidth,height: _sharedPurchaseHeight,offset: _offset));}}}///Get the coordinates of the widget on the screen.Widgets must be rendered completely.///获取widget在屏幕上的坐标,widget必须渲染完成static Offset getWidgetLocalToGlobal(BuildContext context) {RenderBox box = context.findRenderObject();return box == null ? Offset.zero : box.localToGlobal(Offset.zero);}相关文章:
flutter显示出底部控件的引导页
需求:同一个页面的两个不同的入口,同一个控件的位置有变化,显示引导页时对应这个控件的引导内容的位置也需要改变;同时半透明底部显示出真实的页面内容。 这样的需要如果切图然后再往页面上贴位置无法精确的对准。 思路࿱…...
常用设计模式——模板方法模式
什么是模板方法模式 模板方法模式:定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。 主要解决:一些方法通用,却要在每一个子类都重写这些方法…...
idea使用git删除本地提交(未推送)
1、找到reset head 2、打开弹窗,在HEAD后面输入^ 结果为HEAD^ 注释: Reset Type 有三种: Mixed(默认方式),保留本地源码,回退 commit 和 index 信息,最常用的方式Soft 回退到某个版本…...
centos 7部署Mysql8.0主从
Mysql官网中关于部署主从的网址 环境准备: 搭建虚拟机和安装Mysql之前的文章中已经涉及,在此不再赘述。 主从IPMysql账号密码主192.168.213.4root/Root1234!从192.168.213.5root/Root1234! 1、主数据库设置 配置my.cnf 一般存放于/etc/。 主从配…...
asp.net docker-compose添加es search
打开docker-compose.yml添加 es-search:image: docker.elastic.co/elasticsearch/elasticsearch:7.17.14 打开docker-compose.override.yml添加 es-search:volumes:- data01:/usr/share/elasticsearch/dataports:- 9200:9200 docker集群中添加es search成功...
工业路由器网关的网络协议之NAT技术
在物联网通讯领域,NAT技术能将内网的一个私有IP转换成一个公网IP去接入互联网,解决组建局域网络时私有IP地址无法在公网上进行路由的问题。 NAT(Network Address Translation)的三种方式: 静态NAT 1、一个私有IP对应…...
【亲测可用】SpringBoot使用Redis的Lettuce连接池报RedisCommandTimeoutException
目录 一、问题详情 二、根本原因 三、解决方案 一、问题详情 在最近新项目的开发当中,当项目刚启动的时候访问Redis服务一切正常,但是过了几分钟后再次访问Redis就报如下错误。 Redis command timed out; nested exception is io.lettuce.core.RedisCommandTimeoutExcept…...
When Urban Region Profiling Meets Large Language Models
本文是LLM系列文章,针对《When Urban Region Profiling Meets Large Language Models》的翻译。 当城市区域轮廓遇到大型语言模型时 摘要1 引言2 前言3 方法4 实验5 结论与未来工作 摘要 基于网络数据的城市区域概况对城市规划和可持续发展至关重要。我们见证了LL…...
【python】最大的偶数
题目: """ 给出一个由非负整数组成的序列 A (A1,A2,A3,....,Av)。这个序列的长度为N判断是否存在一个偶数可以表示为在A中两个不同元素的和。若存在,找到最大的偶数,否则输出”-…...
QT 实现两款自定义的温度计/湿度控件
文章目录 0 引入1、带有标尺的温度/湿度计控件1.头文件2.核心代码 2、竖起来的温度/湿度计控件1.头文件2.实现 3、引用 0 引入 QT原生控件没有实现如仪表盘或者温度计的控件,只好自己实现,文章代码部分参考引用的文章。直接上图 图一 带有标尺的温度计…...
Fourier分析导论——第4章——Fourier级数的一些应用(E.M. Stein R. Shakarchi)
第 4 章 傅里叶级数的一些应用 Fourier series and analogous expansions intervene very naturally in the general theory of curves and surfaces. In effect, this theory, conceived from the point of view of analysis, deals obviously with the study of arbitra…...
c语言使用fdk_aac库对aac音频解码为pcm
//示例为adts的aac流数据(adts数据可以每一包都可以独立解析不需要拼凑) //解码数据的采样率同解码前的采样率,如果不满足需求,需要对数据进行重采样 #include <aacdecoder_lib.h>int m_fd -1; int m_fd2 -1;void aac2pc…...
zustand管理工具--React
npm i zustand 1.函数参数必须返回一个对象 对象内部编写状态数据和方法 2.set是用来修改数据的专门方法必须调用它来修改数据 import { useEffect } from "react"; import { create } from "zustand";// 1. 创建store const goodsStore create((set) …...
Elasticsearch内存分析
文章目录 Elasticsearch JVM内存由哪些部分组成Indexing BufferNode Query CacheShard Request CacheField Data CacheSegments Cache查询 非堆内存内存压力mat分析es的jvm缓存监控 Elasticsearch JVM内存由哪些部分组成 官方建议Elasticsearch设置堆内存为32G,因为…...
Alert警告提示(antd-design组件库)简单使用
1.Alert警告提示 警告提示,展现需要关注的信息。 2.何时使用 当某个页面需要向用户显示警告的信息时。 非浮层的静态展现形式,始终展现,不会自动消失,用户可以点击关闭。 组件代码来自: 警告提示 Alert - Ant Design 3…...
Linux提权方法总结
1、内核漏洞提权 利用内核漏洞提取一般三个环节:首先对目标系统进行信息收集,获取系统内核信息及版本信息 第二步,根据内核版本获取对应的漏洞以及exp 第三步,使用exp对目标进行攻击,完成提权 注:此处可…...
力扣第300题 最长递增子序列 c++ 动态规划题 附Java代码
题目 300. 最长递增子序列 中等 相关标签 数组 二分查找 动态规划 给你一个整数数组 nums ,找到其中最长严格递增子序列的长度。 子序列 是由数组派生而来的序列,删除(或不删除)数组中的元素而不改变其余元素的顺序。例…...
Si3262 集成低功耗SOC 三合一智能门锁应用芯片
Si3262 是一款G度集成的低功耗 SOC 芯片,其集成了基于 RISC-V 核的低功耗MCU 和工作在 13.56MHz 的非接触式读写器模块。 读写器模块支持 ISO/IEC 14443 A/B/MIFARE 协议,支持自动载波侦测功能(ACD)。无需外W其他电路,…...
linux rsyslog介绍
Rsyslog网址:https://www.rsyslog.com/ Rsyslog is the rocket-fast system for log processing. It offers high-performance, great security features and a modular design. While it started as a regular syslogd, rsyslog has evolved into a kind of swis…...
项目部署之安装和配置Canal
1.Canal介绍 Canal是阿里巴巴的一个开源项目,基于java实现,整体已经在很多大型的互联网项目生产环境中使用,包括阿里、美团等都有广泛的应用,是一个非常成熟的数据库同步方案,基础的使用只需要进行简单的配置即可。 …...
利用ngx_stream_return_module构建简易 TCP/UDP 响应网关
一、模块概述 ngx_stream_return_module 提供了一个极简的指令: return <value>;在收到客户端连接后,立即将 <value> 写回并关闭连接。<value> 支持内嵌文本和内置变量(如 $time_iso8601、$remote_addr 等)&a…...
PHP和Node.js哪个更爽?
先说结论,rust完胜。 php:laravel,swoole,webman,最开始在苏宁的时候写了几年php,当时觉得php真的是世界上最好的语言,因为当初活在舒适圈里,不愿意跳出来,就好比当初活在…...
YSYX学习记录(八)
C语言,练习0: 先创建一个文件夹,我用的是物理机: 安装build-essential 练习1: 我注释掉了 #include <stdio.h> 出现下面错误 在你的文本编辑器中打开ex1文件,随机修改或删除一部分,之后…...
五年级数学知识边界总结思考-下册
目录 一、背景二、过程1.观察物体小学五年级下册“观察物体”知识点详解:由来、作用与意义**一、知识点核心内容****二、知识点的由来:从生活实践到数学抽象****三、知识的作用:解决实际问题的工具****四、学习的意义:培养核心素养…...
postgresql|数据库|只读用户的创建和删除(备忘)
CREATE USER read_only WITH PASSWORD 密码 -- 连接到xxx数据库 \c xxx -- 授予对xxx数据库的只读权限 GRANT CONNECT ON DATABASE xxx TO read_only; GRANT USAGE ON SCHEMA public TO read_only; GRANT SELECT ON ALL TABLES IN SCHEMA public TO read_only; GRANT EXECUTE O…...
学习STC51单片机31(芯片为STC89C52RCRC)OLED显示屏1
每日一言 生活的美好,总是藏在那些你咬牙坚持的日子里。 硬件:OLED 以后要用到OLED的时候找到这个文件 OLED的设备地址 SSD1306"SSD" 是品牌缩写,"1306" 是产品编号。 驱动 OLED 屏幕的 IIC 总线数据传输格式 示意图 …...
数据链路层的主要功能是什么
数据链路层(OSI模型第2层)的核心功能是在相邻网络节点(如交换机、主机)间提供可靠的数据帧传输服务,主要职责包括: 🔑 核心功能详解: 帧封装与解封装 封装: 将网络层下发…...
【python异步多线程】异步多线程爬虫代码示例
claude生成的python多线程、异步代码示例,模拟20个网页的爬取,每个网页假设要0.5-2秒完成。 代码 Python多线程爬虫教程 核心概念 多线程:允许程序同时执行多个任务,提高IO密集型任务(如网络请求)的效率…...
3-11单元格区域边界定位(End属性)学习笔记
返回一个Range 对象,只读。该对象代表包含源区域的区域上端下端左端右端的最后一个单元格。等同于按键 End 向上键(End(xlUp))、End向下键(End(xlDown))、End向左键(End(xlToLeft)End向右键(End(xlToRight)) 注意:它移动的位置必须是相连的有内容的单元格…...
鸿蒙DevEco Studio HarmonyOS 5跑酷小游戏实现指南
1. 项目概述 本跑酷小游戏基于鸿蒙HarmonyOS 5开发,使用DevEco Studio作为开发工具,采用Java语言实现,包含角色控制、障碍物生成和分数计算系统。 2. 项目结构 /src/main/java/com/example/runner/├── MainAbilitySlice.java // 主界…...
