flutter显示出底部控件的引导页

news2024/11/23 13:28:30

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

入口一进入时:
在这里插入图片描述
入口二进入时:
在这里插入图片描述

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

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

xcode SDK does not contain ‘libarclite‘

SDK does not contain libarclite at the path /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/arc/libarclite_iphonesimulator.a; try increasing the minimum deployment target解决方法 iOS13以上

线性系统的激励和响应以及与系统特性的联系

线性系统的激励和响应以及与系统特性的联系 一、系统激励和响应的定义 一个线性系统可以用一个常系数线性微分方程来表示。比如,RC串联电路,电容器两端的电压 u c ( t ) u_c(t) uc​(t)所满足的关系式为: R C d u c d t u c e ( t ) RC\…

掌动智能信创测试服务内容是什么

掌动智能信创测试对软件厂商依据系列《产品适配认证技术规范》,开展数据库、中间件、应用软件等产品适配认证服务,验证其在信创环境下的功能、性能、安全性等,进一步提高产品质量的可信度。 掌动智能信创测试服务内容 1、软件产品选型测试:在…

LabVIEW如何才能得到共享变量的引用

LabVIEW如何才能得到共享变量的引用 有一个LabVIEW 库文件 (.lvlib) ,其中有一些定义好的共享变量。但需要得到每个共享变量的引用以便在程序运行时访问其属性。 共享变量的属性定义在“变量”类属性节点中。为了访问变量类,共享变量的引用必须连接到变…

SQL必知会(二)-SQL查询篇(2)-排序检索数据

第3课、排序检索数据 排序数据 OEDER BY:排序 进行排序 1)按单个列排序 需求: 以 prod_name 字段按照字母顺序排序 SELECT prod_name FROM Products ORDER BY prod_name; -- 以 prod_name 列按照字母顺序排序输出结果: 2&…

vpn概述总结

一、VPN背景 在Internet的传输中 绝大部分数据的内容都是明文传输的 存在很多安全隐患 如窃听 篡改 冒充 总部 分公司 办事处 出差人员 合作单位需要访问总部网络资源的问题 二,VPN定义(Vitual Private Network,虚拟私有网)&…

IP代理中的动态轮换住宅代理是什么?有何作用?

随着越来越多的企业完善网络活动,IP代理的重要性变得显而易见。代理可确保顺利、安全且不受限制地访问互联网的大量资源。在不同类型的代理中,轮换代理脱颖而出,那么他哪里有别于其他IP代理呢? 一、什么是动态轮换代理&#xff1f…

SMT:引领新时代公链赛道的龙头之选!

近年来,区块链技术的应用越来越广泛,而公链作为区块链技术的重要组成部分,也得到了越来越多的关注。SMT公链作为新兴的公链项目,正在吸引着越来越多的关注。 SMT平台由拥有丰富金融行业和区块链技术经验的专业团队运营&#xff0…

【数组】【快慢指针】Leetcode 27 移除元素

【数组】【快慢指针】Leetcode 27 移除元素 解法1 ---------------🎈🎈题目链接🎈🎈------------------- 解法1 时间复杂度O(N) 空间复杂度O(1) class Solution {public int removeElement(int[] nums, int val) {// 快慢指针…

2023年WebAssembly 现状

WebAssembly 2023的调查已经结束,结果揭晓……真的很吸引人! 如果你想要简短的总结,这里有一些亮点: Rust 和 JavaScript 的使用仍在继续增加,但更值得注意的变化发生在下面—— Swift 和 Zig 的采纳率都有了显著的增长…

BigDecimal 类型的累加操作

BigDecimal 累加操作 .add操作

如何在Linux上搭建本地Docker Registry并实现远程连接

Linux 本地 Docker Registry本地镜像仓库远程连接 文章目录 Linux 本地 Docker Registry本地镜像仓库远程连接1. 部署Docker Registry2. 本地测试推送镜像3. Linux 安装cpolar4. 配置Docker Registry公网访问地址5. 公网远程推送Docker Registry6. 固定Docker Registry公网地址…

java数据结构(红黑树)set集合 HashSet HashSet三个问题 LinkedHashSetTreeSet TreeSet集合默认规则排序规则

目录 数据结构(红黑树)红黑规则红黑树添加结点规则 set集合小结HashSet HashSet三个问题LinkedHashSet小结 TreeSetTreeSet集合默认规则排序规则(第一种排序方法)方式二练习 小练 总结总结 集合的使用应该怎么选择 数据结构(红黑树) 红黑规则 后代节点就是比如13根结点 13下面的…

JavaSE基础语法

文章目录 概述发展历程版本环境安装main方法注释标识符关键字数据类型与变量四类八种基本类型常量变量概念定义 类型转换自动类型转换强制类型转换类型提升 字符串类型 运算符算数运算符增量运算符自增自减运算符关系运算符逻辑运算符逻辑与 &&逻辑或 ||逻辑非 !短路求…

can only concatenate list (not “range“) to list

在Python中,你不能直接将range对象与列表进行连接。range对象是数字序列,而列表是元素的序列。这两种类型的数据无法直接连接。 如果你想将一个range对象转化为列表,然后将其与另一个列表连接,你可以先将range对象转化为列表&…

Xshell如何下载文件到本地

法一:命令下载 1、连接到远程服务器并登录 2、使用cd命令进入要下载文件的目录 3、使用以下命令下载文件: scp usernameremote:/path/to/file /path/to/local/directoryusername 远程服务器的用户名 remote 远程服务器的IP地址或主机名 /path/to/file …

windows环境下PHP7.4多线程设置

windows环境下的PHP设置多线程时有一定的难度,难点主要是PHP版本的选择,多线程扩展的选择,以及相关的设置等。 环境 windows 10php-7.4.33-Win32-vc15-x64php_parallel-1.1.4-7.4-ts-vc15-x64phpstudy 8.1.1.2 为了快速的部署PHP环境&…

css控制卡片内部的左右布局

先放效果图 纯css样式 可以根据需求进行更改 <template> <!-- 卡片盒子 --><div class"card_box "><el-card class"box-card w400" v-for"(item,index) in cardList" :key"index"><div slot"heade…

<sa8650>qcxserver 之 QCarCam 6.X API介绍 (第二部分)

@[TOC](<sa8650>qcxserver 之 QCarCam 6.X API介绍 (第二部分)) 2.6 帧信息定 帧信息定义包括缓冲区列表ID、缓冲区索引、帧序列号、每个批处理帧的时间戳、隔行扫描字段类型和标志。 2.6.1 QCarCamHWTimestamp_t 硬件时间戳定义 2.6.2 QCarCamBatchFramesInfo_t 2.6.3…

数字通信和fpga概述——杜勇版本学习笔记

1数字通信处理流程 脉冲调制是每个数字通信系统中间必不可少的环节&#xff0c;通常是使用升余弦滚降滤波器来实现。 超外差接收机原理是利用本地产生的振荡波与输入信号混频&#xff0c;将输入信号频率变换为某个预先确定的频率的方法。超外差原理最早是由E.H.阿姆斯特朗于1…