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实现,整体已经在很多大型的互联网项目生产环境中使用,包括阿里、美团等都有广泛的应用,是一个非常成熟的数据库同步方案,基础的使用只需要进行简单的配置即可。 …...
MPNet:旋转机械轻量化故障诊断模型详解python代码复现
目录 一、问题背景与挑战 二、MPNet核心架构 2.1 多分支特征融合模块(MBFM) 2.2 残差注意力金字塔模块(RAPM) 2.2.1 空间金字塔注意力(SPA) 2.2.2 金字塔残差块(PRBlock) 2.3 分类器设计 三、关键技术突破 3.1 多尺度特征融合 3.2 轻量化设计策略 3.3 抗噪声…...
FastAPI 教程:从入门到实践
FastAPI 是一个现代、快速(高性能)的 Web 框架,用于构建 API,支持 Python 3.6。它基于标准 Python 类型提示,易于学习且功能强大。以下是一个完整的 FastAPI 入门教程,涵盖从环境搭建到创建并运行一个简单的…...
UDP(Echoserver)
网络命令 Ping 命令 检测网络是否连通 使用方法: ping -c 次数 网址ping -c 3 www.baidu.comnetstat 命令 netstat 是一个用来查看网络状态的重要工具. 语法:netstat [选项] 功能:查看网络状态 常用选项: n 拒绝显示别名&#…...
CentOS下的分布式内存计算Spark环境部署
一、Spark 核心架构与应用场景 1.1 分布式计算引擎的核心优势 Spark 是基于内存的分布式计算框架,相比 MapReduce 具有以下核心优势: 内存计算:数据可常驻内存,迭代计算性能提升 10-100 倍(文档段落:3-79…...
相机从app启动流程
一、流程框架图 二、具体流程分析 1、得到cameralist和对应的静态信息 目录如下: 重点代码分析: 启动相机前,先要通过getCameraIdList获取camera的个数以及id,然后可以通过getCameraCharacteristics获取对应id camera的capabilities(静态信息)进行一些openCamera前的…...
UR 协作机器人「三剑客」:精密轻量担当(UR7e)、全能协作主力(UR12e)、重型任务专家(UR15)
UR协作机器人正以其卓越性能在现代制造业自动化中扮演重要角色。UR7e、UR12e和UR15通过创新技术和精准设计满足了不同行业的多样化需求。其中,UR15以其速度、精度及人工智能准备能力成为自动化领域的重要突破。UR7e和UR12e则在负载规格和市场定位上不断优化…...
【开发技术】.Net使用FFmpeg视频特定帧上绘制内容
目录 一、目的 二、解决方案 2.1 什么是FFmpeg 2.2 FFmpeg主要功能 2.3 使用Xabe.FFmpeg调用FFmpeg功能 2.4 使用 FFmpeg 的 drawbox 滤镜来绘制 ROI 三、总结 一、目的 当前市场上有很多目标检测智能识别的相关算法,当前调用一个医疗行业的AI识别算法后返回…...
Java + Spring Boot + Mybatis 实现批量插入
在 Java 中使用 Spring Boot 和 MyBatis 实现批量插入可以通过以下步骤完成。这里提供两种常用方法:使用 MyBatis 的 <foreach> 标签和批处理模式(ExecutorType.BATCH)。 方法一:使用 XML 的 <foreach> 标签ÿ…...
基于IDIG-GAN的小样本电机轴承故障诊断
目录 🔍 核心问题 一、IDIG-GAN模型原理 1. 整体架构 2. 核心创新点 (1) 梯度归一化(Gradient Normalization) (2) 判别器梯度间隙正则化(Discriminator Gradient Gap Regularization) (3) 自注意力机制(Self-Attention) 3. 完整损失函数 二…...
掌握 HTTP 请求:理解 cURL GET 语法
cURL 是一个强大的命令行工具,用于发送 HTTP 请求和与 Web 服务器交互。在 Web 开发和测试中,cURL 经常用于发送 GET 请求来获取服务器资源。本文将详细介绍 cURL GET 请求的语法和使用方法。 一、cURL 基本概念 cURL 是 "Client URL" 的缩写…...
