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);
  }

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

特殊矩阵的压缩存储(对称矩阵,三角矩阵,三对角矩阵,稀疏矩阵)

目录 1.数组的存储结构1.—维数组2.二维数组1.行优先存储2.列优先存储 2.特殊矩阵1.对称矩阵1.行优先存储 2.三角矩阵1.上三角矩阵2.下三角矩阵 3.三对角矩阵(带状矩阵)4.稀疏矩阵 1.数组的存储结构 1.—维数组 各数组元素大小相同,且物理上…

Fabric区块链浏览器搭建

目录 一、创建区块链浏览器相关目录二、配置docker-compose三、配置区块链浏览器四、启动区块链浏览器 书接这一回 Fabric二进制建链,在建好链之后,将为这条链部署一个区块链浏览器。 Hyperledger Fabric区块链浏览器地址:https://github.co…

多目标优化算法:多目标霸王龙优化算法(MOTROA)MATLAB

一、霸王龙优化算法 霸王龙优化算法(Tyrannosaurus optimization,TROA)由Venkata Satya Durga Manohar Sahu等人于2023年提出,该算法模拟霸王龙的狩猎行为,具有搜索速度快等优势。 参考文献: [1]Venkata …

com.alibaba:tools:jar com.alibaba:jconsole:jar

com.alibaba:tools:jar com.alibaba:jconsole:jar

时间序列预测模型实战案例(十)(个人创新模型)通过堆叠CNN、GRU、LSTM实现多元预测和单元预测

本文介绍 本篇博客为大家讲解的是通过组堆叠CNN、GRU、LSTM个数,建立多元预测和单元预测的时间序列预测模型,其效果要比单用GRU、LSTM效果好的多,其结合了CNN的特征提取功能、GRU和LSTM用于处理数据中的时间依赖关系的功能。通过将它们组合在…

1-前端基本知识-HTML

1-前端基本知识-HTML 文章目录 1-前端基本知识-HTML总体概述什么是HTML?超文本标记语言 HTML基础结构文档声明根标签头部元素主体元素注释 HTML概念词汇:标签、属性、文本、元素HTML基本语法规则HTML常见标签标题标签段落标签换行标签列表标签超链接标签…

【大数据】Apache NiFi 数据同步流程实践

Apache NiFi 数据同步流程实践 1.环境2.Apache NIFI 部署2.1 获取安装包2.2 部署 Apache NIFI 3.NIFI 在手,跟我走!3.1 准备表结构和数据3.2 新建一个 Process Group3.3 新建一个 GenerateTableFetch 组件3.4 配置 GenerateTableFetch 组件3.5 配置 DBCP…

【文末送书】十大排序算法及C++代码实现

欢迎关注博主 Mindtechnist 或加入【智能科技社区】一起学习和分享Linux、C、C、Python、Matlab,机器人运动控制、多机器人协作,智能优化算法,滤波估计、多传感器信息融合,机器学习,人工智能等相关领域的知识和技术。关…

打造一个可视化接口自动化测试系统

现如今,接口开发几乎成为一个互联网公司的标配了,无论是web还是app,哪怕是小程序,都离不开接口作为支撑,当然,这里的接口范围很广,从http到websocket,再到rpc,只要能实现…

2022ICPC济南站

K Stack Sort 题意:给你一个长度为n的排列,设有m个栈,你需要将这n个数按出现顺序入栈,每次入栈操作从m个栈中选择一个栈从栈顶入栈。当所有元素入栈完成后,需要不断选择栈,将栈中元素弹空。需满足出栈顺序…

ubuntu, nvidia driver, cuda, cudnn, pytorch-gpu版本安装

文章目录 1.常用指令1.1查看cpu是intel还是amd:1.2.查看ubuntu版本1.3.查看架构1.4.查看已安装的nvidia驱动1.5.进入tty模式 2.安装ubuntu22.04 和 nvidia 驱动3.ubuntu 安装 anaconda4.安装pytorch gpu版本5.安装完整版cuda 和 cudnn6.nvidia-driver, cuda-toolkit, cudnn 1.常…

OpenCV 在ImShow窗体上选择感兴趣的区域

窗体上选择感兴趣ROI区域 在计算机视觉处理中, 通常是针对图像中的一个特定区域进行处理, 有时候这个特定区域需要人来选择, OpenCV 也提供了窗口选择ROI机制. 窗体支持两种选择ROI区域的方法, 一个是单选, 一个是多选, 操作方法如下: 单选: 通过鼠标在屏幕上选择区域, 然后通过…

第三章:人工智能深度学习教程-基础神经网络(第三节-Tensorflow 中的多层感知器学习)

在本文中,我们将了解多层感知器的概念及其使用 TensorFlow 库在 Python 中的实现。 多层感知器 多层感知也称为MLP。它是完全连接的密集层,可将任何输入维度转换为所需的维度。多层感知是具有多个层的神经网络。为了创建神经网络,我们将神…

Flink SQL -- 概述

1、Flink SQL中的动态表和连续查询 1、动态表: 因为Flink是可以做实时的,数据是在不断的变化的,所以动态表指的是Flink中一张实时变换的表,表中会不断的有新的数据。但是这张表并不是真正的物理表。 2、连续查询: 连续…

深度学习之基于YoloV5交通信号标志识别系统

欢迎大家点赞、收藏、关注、评论啦 ,由于篇幅有限,只展示了部分核心代码。 文章目录 一项目简介 二、功能三、系统四. 总结 一项目简介 基于YoloV5交通信号标志识别系统介绍 基于YoloV5的交通信号标志识别系统是一种深度学习应用,旨在通过使…

kotlin 基本语法

const val INFO "ZZZ is Success Result" fun main(){ var name: String? "zzz" name null name?.capitalize() //?问号的意思是如果name是null ,后面的方法不执行,如果name不是null,后面方法执行 var name: String? &q…

xdcms漏洞合集-漏洞复现

目录 xdcms v3.0.1漏洞 环境搭建 代码审计 目录总览 配置文件总览 登陆处sql注入 漏洞分析 漏洞复现 注册处sql注入漏洞 漏洞分析 漏洞复现 getshell 任意文件删除 xdcms订餐网站管理系统v1.0漏洞 简介 环境搭建 全局变量的覆盖 漏洞分析 漏洞复现 后台任意…

Leetcode—102.二叉树的层序遍历【中等】

2023每日刷题(二十四) Leetcode—102.二叉树的层序遍历 C语言BFS实现代码 /*** Definition for a binary tree node.* struct TreeNode {* int val;* struct TreeNode *left;* struct TreeNode *right;* };*/ /*** Return an array of arr…

API接口自动化测试

本节介绍,使用python实现接口自动化实现。 思路:讲接口数据存放在excel文档中,读取excel数据,将每一行数据存放在一个个列表当中。然后获取URL,header,请求体等数据,进行请求发送。 结构如下 excel文档内容如下&#x…

Spring Task定时任务框架

二十四、Spring Task 24.1 介绍 Spring Task 是Spring框架提供的任务调度工具,可以按照约定的时间自动执行某个代码逻辑。 定位:定时任务框架 作用:定时自动执行某段Java代码 为什么要在Java程序中使用Spring Task? 应用场景…