Flutter(三):Stack、Positioned、屏幕相关尺寸、Navigator路由跳转

news2025/1/23 3:22:19

页面尺寸

在这里插入图片描述

  • 通知栏高度:MediaQuery.of(context).padding.top
  • 顶部导航高度:kToolbarHeight
  • 底部导航高度:kBottomNavigationBarHeight
  • 屏幕宽:MediaQuery.of(context).size.width
  • 屏幕高:MediaQuery.of(context).size.height
import 'package:flutter/material.dart';

// 描述文本
class DescText extends StatelessWidget {
  final String title;
  final double size;

  const DescText(this.title, {super.key, this.size = 10});

  
  Widget build(BuildContext context) {
    return Center(
      child: Text(title, style: TextStyle(fontSize: size, decoration: TextDecoration.none)),
    );
  }
}

class ScreenSizePage extends StatefulWidget {
  const ScreenSizePage({super.key});

  
  State<ScreenSizePage> createState() => _ScreenSizePage();
}

class _ScreenSizePage extends State<ScreenSizePage> {
  
  Widget build(BuildContext context) {
    // 屏幕宽度
    double screenWidth = MediaQuery
        .of(context)
        .size
        .width;
    // 屏幕高度
    double screenHeight = MediaQuery
        .of(context)
        .size
        .height;
    // 通知栏高度
    double noticeHeight = MediaQuery
        .of(context)
        .padding
        .top;
    // 屏幕中心
    double centerX = screenWidth / 2;
    double centerY = screenHeight / 2;

    return Container(
      width: double.infinity,
      height: double.infinity,
      color: Colors.grey,
      child: Stack(
        children: [
          Positioned(
            top: 0,
            left: 0,
            child: Container(
              width: screenWidth,
              height: noticeHeight,
              color: Colors.yellow,
              child: DescText('通知栏高度($noticeHeight):MediaQuery.of(context).padding.top'),
            ),
          ),
          Positioned(
            top: noticeHeight,
            left: 0,
            child: Container(
              width: screenWidth,
              height: kToolbarHeight,
              color: Colors.blue,
              child: const DescText('顶部导航高度($kToolbarHeight):kToolbarHeight', size: 16),
            ),
          ),
          Positioned(
            bottom: 0,
            left: 0,
            child: Container(
              width: screenWidth,
              height: kBottomNavigationBarHeight,
              color: Colors.green,
              child: const DescText(
                  '底部导航高度($kBottomNavigationBarHeight):kBottomNavigationBarHeight', size: 14),
            ),
          ),
          Positioned(
            bottom: 80,
            left: 0,
            child: Container(
              width: screenWidth,
              height: 30,
              color: const Color.fromRGBO(255, 255, 0, .3),
              child: DescText('屏幕宽($screenWidth):MediaQuery.of(context).size.width'),
            ),
          ),
          Positioned(
            top: 0,
            right: 80,
            child: Container(
              width: 30,
              height: screenHeight,
              color: const Color.fromRGBO(0, 255, 255, .3),
              child: RotatedBox(
                quarterTurns: 45,
                child: DescText(
                    '屏幕高($screenHeight):MediaQuery.of(context).size.height', size: 12),
              ),
            ),
          ),
          Positioned(
            top: centerY - 18,
            left: centerX - 50,
            child: MaterialButton(
              onPressed: () => Navigator.pop(context, true),
              // 返回上一页
              color: Colors.white,
              textColor: Colors.blue,
              minWidth: 100,
              height: 36,
              child: const Text('返 回'),
            ),
          ),
        ],
      ),
    );
  }
}

Stack布局

SelectWidget组件参考 https://blog.csdn.net/weixin_43526371/article/details/136256386

在这里插入图片描述

import 'package:flutter/material.dart';
import 'package:flutter_app/components/select_widget.dart';

class StackPage extends StatefulWidget {
  const StackPage({super.key});

  
  State<StackPage> createState() => _StackPage();
}

class _StackPage extends State<StackPage> {
  AlignmentDirectional alignmentValue = AlignmentDirectional.topStart;
  List<SelectOption> alignmentList = [
    SelectOption(label: 'topStart', value: AlignmentDirectional.topStart),
    SelectOption(label: 'topCenter', value: AlignmentDirectional.topCenter),
    SelectOption(label: 'topEnd', value: AlignmentDirectional.topEnd),
    SelectOption(label: 'centerStart', value: AlignmentDirectional.centerStart),
    SelectOption(label: 'center', value: AlignmentDirectional.center),
    SelectOption(label: 'centerEnd', value: AlignmentDirectional.centerEnd),
    SelectOption(label: 'bottomStart', value: AlignmentDirectional.bottomStart),
    SelectOption(label: 'bottomCenter', value: AlignmentDirectional.bottomCenter),
    SelectOption(label: 'bottomEnd', value: AlignmentDirectional.bottomEnd),
  ];

  TextDirection textDirectionValue = TextDirection.ltr;
  List<SelectOption> textDirectionList = [
    SelectOption(label: 'ltr', value: TextDirection.ltr),
    SelectOption(label: 'rtl', value: TextDirection.rtl),
  ];

  
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Stack 布局')),
      body: Scaffold(
        appBar: PreferredSize(
          preferredSize: const Size.fromHeight(50),
          child: Row(
            mainAxisAlignment: MainAxisAlignment.spaceBetween,
            children: [
              Expanded(
                flex: 1,
                child: SelectWidget(
                  title: 'AlignmentDirectional',
                  options: alignmentList,
                  onChange: (SelectOption selectOption) {
                    setState(() {
                      alignmentValue = selectOption.value as AlignmentDirectional;
                    });
                  },
                ),
              ),
              Expanded(
                flex: 1,
                child: SelectWidget(
                  title: 'TextDirection',
                  options: textDirectionList,
                  onChange: (SelectOption selectOption) {
                    setState(() {
                      textDirectionValue = selectOption.value as TextDirection;
                    });
                  },
                ),
              ),
            ],
          ),
        ),
        body: Container(
          width: double.infinity,
          height: double.infinity,
          color: Colors.grey,
          child: Stack(
            alignment: alignmentValue,
            textDirection: textDirectionValue,
            children: [
              Container(width: 250, height: 250, color: Colors.red),
              Container(width: 200, height: 200, color: Colors.green),
              Container(width: 150, height: 150, color: Colors.blue),
              Container(width: 100, height: 100, color: Colors.black),
            ],
          ),
        ),
      ),
    );
  }
}

Positioned布局

在这里插入图片描述

import 'package:flutter/material.dart';

class PositionedPage extends StatefulWidget {
  const PositionedPage({super.key});

  
  State<PositionedPage> createState() => _PositionedPage();
}

class _PositionedPage extends State<PositionedPage> {
  
  Widget build(BuildContext context) {
    // 屏幕宽度
    double screenWidth = MediaQuery
        .of(context)
        .size
        .width;
    // 屏幕高度
    double screenHeight = MediaQuery
        .of(context)
        .size
        .height;
    // 通知栏高度
    double noticeHeight = MediaQuery
        .of(context)
        .padding
        .top;
    // 屏幕中心
    double centerX = screenWidth / 2;
    double centerY = (screenHeight - noticeHeight - kToolbarHeight - kBottomNavigationBarHeight) /
        2;

    return Scaffold(
      appBar: AppBar(title: const Text('Positioned 布局')),
      body: Container(
        width: double.infinity,
        height: double.infinity,
        color: Colors.grey,
        child: Stack(
          children: [
            // 中
            Positioned(
              top: centerY - 50,
              left: centerX - 50,
              child: Container(width: 100, height: 100, color: Colors.orange),
            ),
            // 左上
            Positioned(
              top: 10,
              left: 10,
              child: Container(
                width: 120,
                height: 120,
                color: Colors.red,
                child: Stack(
                  children: [
                    Positioned(top: 20,
                        left: 20,
                        child: Container(width: 50, height: 50, color: Colors.black)),
                  ],
                ),
              ),
            ),
            // 右上
            Positioned(
              top: 10,
              right: 10,
              child: Container(
                width: 120,
                height: 120,
                color: Colors.green,
                child: Stack(
                  children: [
                    Positioned(top: 20,
                        right: 20,
                        child: Container(width: 50, height: 50, color: Colors.blue)),
                  ],
                ),
              ),
            ),
            // 左下
            Positioned(
              bottom: 10,
              left: 10,
              child: Container(
                width: 120,
                height: 120,
                color: Colors.blue,
                child: Stack(
                  children: [
                    Positioned(bottom: 20,
                        left: 20,
                        child: Container(width: 50, height: 50, color: Colors.green)),
                  ],
                ),
              ),
            ),
            // 右下
            Positioned(
              bottom: 10,
              right: 10,
              child: Container(
                width: 120,
                height: 120,
                color: Colors.black,
                child: Stack(
                  children: [
                    Positioned(bottom: 20,
                        right: 20,
                        child: Container(width: 50, height: 50, color: Colors.red)),
                  ],
                ),
              ),
            ),
          ],
        ),
      ),
      bottomNavigationBar: BottomNavigationBar(
        items: const [
          BottomNavigationBarItem(icon: Icon(Icons.home), label: 'HOME'),
          BottomNavigationBarItem(icon: Icon(Icons.book), label: 'BOOK'),
        ],
      ),
    );
  }
}

路由组件

在这里插入图片描述

路由组件

import 'package:flutter/material.dart';
import 'package:flutter_app/views/RowColumnPage.dart';
import 'package:flutter_app/views/StackPage.dart';
import 'package:flutter_app/views/ScreenSizePage.dart';
import 'package:flutter_app/views/PositionedPage.dart';

class MenuItem {
  final String title;
  final Widget widget;

  MenuItem({required this.title, required this.widget});
}

class RouterWidget extends StatelessWidget {
  const RouterWidget({super.key});

  static List<MenuItem> list = <MenuItem>[
    MenuItem(title: "Row、Column 布局", widget: const RowColumnPage()),
    MenuItem(title: "Stack 布局", widget: const StackPage()),
    MenuItem(title: "界面尺寸", widget: const ScreenSizePage()),
    MenuItem(title: "Positioned 布局", widget: const PositionedPage()),
  ];

  
  Widget build(BuildContext context) {
    return ListView.separated(
      itemCount: list.length,
      separatorBuilder: (BuildContext context, int index) => const Divider(height: 1),
      itemBuilder: (BuildContext context, int index) {
        return ListTile(
          title: Text(list[index].title),
          onTap: () {
            Navigator.push(context, MaterialPageRoute(builder: (BuildContext context) => list[index].widget));
          },
        );
      },
    );
  }
}

入口组件

import 'package:flutter/material.dart';
import 'package:flutter_app/components/router_widget.dart';

void main() {
  runApp(const App());
}

class App extends StatefulWidget {
  const App({super.key});

  
  State<App> createState() => _AppState();
}

class _AppState extends State<App> {
  
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false, // 移除右上角DEBUG标识
      home: Scaffold(
        appBar: AppBar(title: const Text("目录")),
        body: const RouterWidget(),
      ),
    );
  }
}

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

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

相关文章

SpringMVC 学习(十)之异常处理

目录 1 异常处理介绍 2 通过 SimpleMappingExceptionResolver 实现 3 通过接口 HandlerExceptionResolver 实现 4 通过 ExceptionHandler 注解实现&#xff08;推荐&#xff09; 1 异常处理介绍 在 SpringMVC中&#xff0c;异常处理器&#xff08;Exceptio…

项目解决方案:海外门店视频汇聚方案(全球性的连锁店、国外连锁店视频接入和汇聚方案)

目 录 一、概述 二、建设目标及需求 2.1 建设目标 2.2 需求描述 2.3 需求分析 三、建设方案设计 3.1 系统方案拓扑图 3.2 方案描述 3.3 服务器配置推荐 四、产品功能 4.1 资源管理平台 &#xff08;1&#xff09;用户权限管理 &#xff08;2&#xff09…

AD9226 65M采样 模数转换

目录 AD9220_ReadTEST AD9220_ReadModule AD9226_TEST_tb 自己再写个 260M的时钟&#xff0c;四分频来提供65M的时钟。 用 vivado 写的 AD9226_ReadTEST module AD9226_ReadTEST( input clk, input rstn,output clk_driver, //模块时钟管脚 input [12:0]IO_data, //模块数…

LACP——链路聚合控制协议

LACP——链路聚合控制协议 什么是LACP&#xff1f; LACP&#xff08;Link Aggregation Control Protocol&#xff0c;链路聚合控制协议&#xff09;是一种基于IEEE802.3ad标准的实现链路动态聚合与解聚合的协议&#xff0c;它是链路聚合中常用的一种协议。 链路聚合组中启用了…

Linux运维-Web服务器的配置与管理(Apache+tomcat)(没成功,最后有失败经验)

Web服务器的配置与管理(Apachetomcat) 项目场景 公司业务经过长期发展&#xff0c;有了很大突破&#xff0c;已经实现盈利&#xff0c;现公司要求加强技术架构应用功能和安全性以及开始向企业应用、移动APP等领域延伸&#xff0c;此时原来开发web服务的php语言已经不适应新的…

云服务器ECS价格表出炉_2024年最新价格表——阿里云

2024年最新阿里云服务器租用费用优惠价格表&#xff0c;轻量2核2G3M带宽轻量服务器一年61元&#xff0c;折合5元1个月&#xff0c;新老用户同享99元一年服务器&#xff0c;2核4G5M服务器ECS优惠价199元一年&#xff0c;2核4G4M轻量服务器165元一年&#xff0c;2核4G服务器30元3…

高防IP简介

高防IP可以防御的有包括但不限于以下类型&#xff1a; SYN Flood、UDP Flood、ICMP Flood、IGMP Flood、ACK Flood、Ping Sweep 等攻击。高防IP专注于解决云外业务遭受大流量DDoS攻击的防护服务。支持网站和非网站类业务的DDoS、CC防护&#xff0c;用户通过配置转发规则&#x…

Nginx反向代理ip透传与负载均衡

前言 上篇介绍了nginx服务器单向代理和动静分离等相关内容&#xff0c;可参考Nginx重写功能和反向代理-CSDN博客&#xff0c;这里就ip透传和负载均衡对nginx反向代理做进一步了解。 目录 一、客户端ip透传 1. 概述 2. 一级代理 2.1 图示 2.2 操作过程 3. 二级代理 3.…

type may not be empty [type-empty]

原因是使用了规范commit信息的工具&#xff0c;你的提交信息不符合规范&#xff0c;所以被拒绝了 commit规范工具 commitlinthusky 解决方式一&#xff1a; 修改提交信息&#xff0c; 使其符合规范 git commit -m "feat: 新功能"使用Git Gui的使用以下格式写提交…

wu-framework-parent 项目明细

wu-framework-parent 介绍 springboot 版本3.2.1 wu-framework-parent 是一款由Java语言开发的框架&#xff0c;目标不写代码但是却能完成功能。 框架涵盖无赖ORM( wu-database-lazy-starter)、仿生组件 、easy框架系列【Easy-Excel、easy-listener、easy-upsert】 授权框架(…

华为ipv6 over ipv4 GRE隧道配置

思路&#xff1a; PC1访问PC2时&#xff0c;会先构造源ipv6为2001:1::2&#xff0c;目的IPV6为2001:2::2的ipv6报文&#xff0c;然后查看PC1的路由表&#xff0c;发送到R1&#xff0c;r1接收后&#xff0c;以目的IPV6地址2001:2::2查询IPV6路由表&#xff0c;出接口为tun0/0/0…

C++ 补充之常用遍历算法

C遍历算法和原理 C标准库提供了丰富的遍历算法&#xff0c;涵盖了各种不同的功能。以下是一些常见的C遍历算法以及它们的概念和原理的简要讲解&#xff1a; for_each&#xff1a;对容器中的每个元素应用指定的函数。 概念&#xff1a;对于给定的容器和一个可调用对象&#xff…

jenkins+kubernetes+git+dockerhub构建devops云平台

Devops简介 k8s助力Devops在企业落地实践 传统方式部署项目为什么发布慢&#xff0c;效率低&#xff1f; 上线一个功能&#xff0c;有多少时间被浪费了&#xff1f; 如何解决发布慢&#xff0c;效率低的问题呢&#xff1f; 什么是Devops&#xff1f; 敏捷开发 提高开发效率&…

Linux中数据库sqlite3的基本命令的使用

数据库概念介绍 数据库安装 首先将本地的三个sqlite3安装包移动到共享文件夹然后在移动到自己创建的文件夹中如下&#xff1a; 然后对安装包进行解压如下&#xff1a;sudo dpkg -i *.deb检查是否安装成功sqlite数据库命令 系统命令 &#xff0c; 都以’.开头 .exit .quit .…

springboot+vue+mysql+easyexcel实现文件导出+导出的excel单元格添加下拉列表

Excel导出 EasyExcel官方文档 官方文档本身写的非常详细&#xff0c;我就是根据官方文档内的写Excel里web中的写实现的导出 后端 对象 需要写一个实体类 其中涉及到一些用到的EasyExcel的注解 ColumnWidth(20) 列宽设为20&#xff0c;自定义的&#xff0c;放在实体类上面是…

ImportError: urllib3 v2.0 only supports OpenSSL 1.1.1+, currently the ‘ssl‘报错解决

安装labelme出错了 根据爆栈的提示信息&#xff0c;我在cmd运行以下命令之后一切正常了&#xff0c;解决了问题&#xff01; pip install urllib31.26.6参考网址&#xff1a;ImportError: urllib3 v2.0 only supports OpenSSL 1.1.1, currently the ‘ssl’ module is compile…

智慧物流之道:数据可视化引领全局监控

在智慧物流的背景下&#xff0c;数据可视化催生了物流管理的全新范式。首先&#xff0c;通过数据可视化&#xff0c;物流企业可以实现对整个供应链的全景式监控。下面我就可以可视化从业者的角度&#xff0c;简单聊聊这个话题。 首先&#xff0c;图表和地图的直观展示使决策者能…

Rust使用calamine读取excel文件,Rust使用rust_xlsxwriter写入excel文件

Rust使用calamine读取已存在的test.xlsx文件全部数据&#xff0c;还读取指定单元格数据&#xff1b;Rust使用rust_xlsxwriter创建新的output.xlsx文件&#xff0c;并写入数据到指定单元格&#xff0c;然后再保存工作簿。 Cargo.toml main.rs /*rust读取excel文件*/ use cala…

mac/windows git ssh 配置多平台账号(入门篇)

目录 引子多账号多平台配置git一、.ssh文件夹路径1.1 mac 系统1.2 windows 系统 二、生成new ssh2.1 mac系统2.2 windows 系统 三、配置 config四、验证五、用ssh方式拉取远程仓库代码 引子 push代码到github仓库时&#xff0c;提示报错。 Push failed Remote: Support for pa…

力扣5. 最长回文子串(双指针、动态规划)

Problem: 5. 最长回文子串 文章目录 题目描述思路复杂度Code 题目描述 思路 思路1&#xff1a;双指针 1.我们利用双指针从中间向两边扩散来判断是否为回文串&#xff0c;则关键是找到以s[i]为中心的回文串&#xff1b; 2.我们编写一个函数string palindrome(string &s, in…