【Flutter】导航组件 NavigationRail 的用法简介

news2024/11/28 7:27:48

​​Material Design 3 定义了三种导航模式,其用法和对应的 Flutter 组件如下所示:

MD3 导航Flutter 组件用途
Navigation barBottomNavigationBar小型屏(宽度小于640)
Navigation drawerDrawer大型屏(宽度大于960)
Navigation railNavigationRail中型屏(宽度介于640和960之间)

这篇博文要介绍的是 NavigationRail 的用法,它主要用于宽度介于640到960之间的中型屏,展现形式如下(最左侧的竖长条):


从设计规范的角度来讲,导航数量最好控制在 3 到 7 个。

如果超出最大数量,可以在顶部放一个菜单按钮,点击后弹出用模态对话框展示的二级导航。

顶部放置菜单按钮
另外,Navigation rail 顶部也可以放置 FAB,用于凸显产品最核心的导航目的地:

在这里插入图片描述

顶部还可以放置 Logo,但做设计时一定要注意,不要给用户造成「这是个按钮」的错觉。

以上是我们从设计层面做出的解读,下面我们从代码层面看一下它的具体用法。

我们知道,Flutter 针对不同屏幕大小内置了三种导航组件:

  • NavigationRail => 中型屏(宽度介于 640 ~ 960 之间)
  • BottomNavigationBar => 小型屏(宽度小于 640)
  • Drawer => 大型屏(宽度大于 960)

这三种组件一般会配合 Scaffold 一起使用,为了让导航组件能够根据屏幕尺寸进行动态调整,我们来实现一个「自适应」的 Scaffold

步骤1:新建一个 dart 源文件,命名为 adaptive_scaffold.dart

步骤2:定义两个查询屏幕类型的小函数:

bool _isLargeScreen(BuildContext context) {
  return MediaQuery.of(context).size.width > 960.0;
}

bool _isMediumScreen(BuildContext context) {
  return MediaQuery.of(context).size.width > 640.0;
}

步骤3:定义一个表示导航目的地的结构体 AdaptiveScaffoldDestination

class AdaptiveScaffoldDestination {
  // 标题
  final String title;

  // 图标
  final IconData icon;

  const AdaptiveScaffoldDestination({
    required this.title,
    required this.icon,
  });
}

步骤4:定义 AdaptiveScaffold

class AdaptiveScaffold extends StatefulWidget {
  final Widget? title;
  final List<Widget> actions;
  final Widget? body;
  final int currentIndex;
  final List<AdaptiveScaffoldDestination> destinations;
  final ValueChanged<int>? onNavigationIndexChange;
  final FloatingActionButton? floatingActionButton;

  // ...
}

每个字段含义如下表所示:

字段含义
title页面标题,可展示于 DrawerAppBar
actions传递给 AppBaractions
body传递给 Scaffoldbody
currentIndex当前导航目的地序号
destinations导航目的地列表
onNavigationIndexChange导航发生改变时的回调
floatingActionButtonFAB

当显示设备为大型屏时,也就是 _isLargeScreen(context) == true 时,页面布局如下图所示:
在这里插入图片描述
整体布局是一个 Row,其子节点从左到右依次为:DrawerVerticalDividerExpanded

Row(
  children: [
    Drawer(),
    VerticalDivider(),
    Expanded(),
  ],
);

其中,Drawer 的子节点是一个 Column

Column(
  children: [
    // 展示页面标题
    DrawerHeader(
      child: Center(
        child: widget.title,
      ),
    ),
    // 列表展示导航条目
    for (var d in widget.destinations)
      ListTile(
        leading: Icon(d.icon),
        title: Text(d.title),
        selected:
            widget.destinations.indexOf(d) == widget.currentIndex,
        onTap: () => _destinationTapped(d),
      ),
  ],
),

竖分割线:

VerticalDivider(
  width: 1,
  thickness: 1,
  color: Colors.grey[300],
),

最后包裹在 Expanded 内的 Scaffold 用于展示页面的主要内容。

Expanded(
  child: Scaffold(
    appBar: AppBar(
      actions: widget.actions,
    ),
    body: widget.body,
    floatingActionButton: widget.floatingActionButton,
  ),
),

以上是大型屏的展示效果。

当显示设备为中型屏时,也就是 _isMediumScreen(context) == true 时,页面布局如下图所示:
在这里插入图片描述
整体布局是一个 Scaffold

Scaffold(
  appBar: AppBar(
    title: widget.title,
    actions: widget.actions,
  ),
  body: Row(
    children: [
      // 导航
      NavigationRail(
        leading: widget.floatingActionButton,
        destinations: [
          ...widget.destinations.map(
            (d) => NavigationRailDestination(
              icon: Icon(d.icon),
              label: Text(d.title),
            ),
          ),
        ],
        selectedIndex: widget.currentIndex,
        onDestinationSelected: widget.onNavigationIndexChange ?? (_) {},
      ),
      VerticalDivider(
        width: 1,
        thickness: 1,
        color: Colors.grey[300],
      ),
      Expanded(
        child: widget.body!,
      ),
    ],
  ),
);

当显示设备为小屏幕时,页面布局如下:

在这里插入图片描述
对应的代码:

Scaffold(
  body: widget.body,
  appBar: AppBar(
    title: widget.title,
    actions: widget.actions,
  ),
  bottomNavigationBar: BottomNavigationBar(
    items: [
      ...widget.destinations.map(
        (d) => BottomNavigationBarItem(
          icon: Icon(d.icon),
          label: d.title,
        ),
      ),
    ],
    currentIndex: widget.currentIndex,
    onTap: widget.onNavigationIndexChange,
  ),
  floatingActionButton: widget.floatingActionButton,
);

以上就是可动态适配屏幕大小的 Scaffold 实现方案,完整代码可移步至 Flutter 官方示例代码 adaptive_scaffold.dart。

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

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

相关文章

Java基础 学习笔记四

标识符 标识符是在源代码中程序员自己有权利命名的单词标识符可以标识 变量名&#xff0c;方法名&#xff0c;类名 标识符命名规则 标识符只能由数字&#xff0c;字符&#xff08;java支持所有国家语言&#xff09;&#xff0c;_&#xff0c; $ 组成&#xff0c;不能含有其他…

基于树莓派实现 --- 智能家居

最效果展示 演示视频链接&#xff1a;基于树莓派实现的智能家居_哔哩哔哩_bilibilihttps://www.bilibili.com/video/BV1Tr421n7BM/?spm_id_from333.999.0.0 &#xff08;PS&#xff1a;房屋模型的搭建是靠纸板箱和淘宝买的家居模型&#xff0c;户型参考了留学时短租的公寓~&a…

软考高级:软件测试阶段概念和例题

作者&#xff1a;明明如月学长&#xff0c; CSDN 博客专家&#xff0c;大厂高级 Java 工程师&#xff0c;《性能优化方法论》作者、《解锁大厂思维&#xff1a;剖析《阿里巴巴Java开发手册》》、《再学经典&#xff1a;《Effective Java》独家解析》专栏作者。 热门文章推荐&am…

Linux课程____进程管理

记录工作日志 script 240319.log CTRLd 退出 cat 240319.log //查看 一、查看进程 1.静态 ps -aux ps -elf 2.动态 top 3.pgrep 查看特定条件的进程 pgrep -l “log” pgrep -l "ssh" pgrep -l -U redhat 4.pstree 查看进程树 pstree -aup 所有…

Flutter 在 Windows 下的开发环境搭建(Flutter SDK 3.19.2)【图文详细教程】

Git 下载与安装 对于 Flutter 3.19&#xff0c;Git 版本需要 2.27 及以上 Git 下载&#xff1a; Git 官网&#xff1a;https://git-scm.com/Git 下载淘宝镜像&#xff1a;https://registry.npmmirror.com/binary.html?pathgit-for-windows/ 对于 Git 的安装教程&#xff0c;…

Go 1.22 - 更加强大的 Go 执行跟踪

原文&#xff1a;Michael Knyszek - 2024.03.14 runtime/trace 包含了一款强大的工具&#xff0c;用于理解和排查 Go 程序。这个功能可以生成一段时间内每个 goroutine 的执行追踪。然后&#xff0c;你可以使用 go tool trace 命令&#xff08;或者优秀的开源工具 gotraceui&a…

Unable to load host key: /etc/ssh/ssh_host_rsa_key

Unable to load host key: /etc/ssh/ssh_host_rsa_key 启动docker镜像时报错 Unable to load host key: /etc/ssh/ssh_host_rsa_key Unable to load host key: /etc/ssh/ssh_host_ecdsa_key Unable to load host key: /etc/ssh/ssh_host_ed25519_key sshd: no hostkeys availa…

多特征变量序列预测(11) 基于Pytorch的TCN-GRU预测模型

往期精彩内容&#xff1a; 时序预测&#xff1a;LSTM、ARIMA、Holt-Winters、SARIMA模型的分析与比较-CSDN博客 风速预测&#xff08;一&#xff09;数据集介绍和预处理-CSDN博客 风速预测&#xff08;二&#xff09;基于Pytorch的EMD-LSTM模型-CSDN博客 风速预测&#xff…

什么是子网掩码、ip地址的网段?如何区分?

IP地址优化网写了很多相关的文章。 有些朋友对于子网掩码、IP地址网段等还不太了解&#xff0c;我们来看看网友经常问到的一些相关问题。 255.255.255.192 的位掩码是什么&#xff1f; 1.什么是子网掩码&#xff1f; 在了解IP地址的网段之前&#xff0c;我们先来了解一下子网…

【RabbitMQ | 第四篇】基于RabbitMQ实现延迟队列

文章目录 4.基于RabbitMQ实现延迟队列4.1延迟队列定义4.2基于DLX&#xff08;死信交换机&#xff09;实现延迟队列4.2.1实现思路4.2.2主要流程4.2.3实战&#xff08;1&#xff09;创建两个消息队列&#xff1a;原始消息队列、死信队列 and 为原始消息队列关联私信交换机&#x…

高精度AI火灾烟雾检测算法,助力打造更加安全的楼宇环境

一、方案背景 近日&#xff0c;南京居民楼火灾事故导致15人死亡的新闻闹得沸沸扬扬&#xff0c;这一事件又激起了大家对楼宇火灾隐患的进一步担忧。事后我们除了思考政府、消防及物业部门应对此事的解决办法&#xff0c;我们还应该思考如何利用现有的技术帮助人们减少此类事情的…

蓝桥杯模块综合——高质量讲解AT24C02,BS18B20,BS1302,AD/DA(PCF8591),超声波模块

AT24C02——就是一个存储的东西&#xff0c;可以给他写东西&#xff0c;掉电不丢失。 void EEPROM_Write(unsigned char * EEPROM_String,unsigned char addr , unsigned char num) {IIC_Start();IIC_SendByte(0xA0);IIC_WaitAck();IIC_SendByte(addr);IIC_WaitAck();while(nu…

非正向图片如何在OCR技术层面去解决?

在OCR&#xff08;Optical Character Recognition&#xff0c;光学字符识别&#xff09;技术中&#xff0c;非正向的图片一般是指倒过来或者没有固定版式的图片&#xff0c;要识别好这类图片确实是一个挑战。这类问题通常涉及到图像预处理、特征提取和识别算法等多个环节。以下…

SpringBoot项目前端Vue访问后端(图片静态资源) 配置

静态资源配置 Configuration public class WebMvcConfig extends WebMvcConfigurationSupport {Value("${file.save-path}")private String fileSavePath;Overrideprotected void addResourceHandlers(ResourceHandlerRegistry registry) {//映射本地文件夹registry…

python大学生健身爱好者交流网站flask-django-nodejs-php

任何系统都要遵循系统设计的基本流程&#xff0c;本系统也不例外&#xff0c;同样需要经过市场调研&#xff0c;需求分析&#xff0c;概要设计&#xff0c;详细设计&#xff0c;编码&#xff0c;测试这些步骤&#xff0c;基于python技术、django/flask框架、B/S机构、Mysql数据…

每日一练:LeeCode-167. 两数之和 II - 输入有序数组【双指针】

给你一个下标从 1 开始的整数数组 numbers &#xff0c;该数组已按 非递减顺序排列 &#xff0c;请你从数组中找出满足相加之和等于目标数 target 的两个数。如果设这两个数分别是 numbers[index1] 和 numbers[index2] &#xff0c;则 1 < index1 < index2 < numbers.…

WanAndroid(鸿蒙版)开发的第六篇

前言 DevEco Studio版本&#xff1a;4.0.0.600 WanAndroid的API链接&#xff1a;玩Android 开放API-玩Android - wanandroid.com 其他篇文章参考&#xff1a; 1、WanAndroid(鸿蒙版)开发的第一篇 2、WanAndroid(鸿蒙版)开发的第二篇 3、WanAndroid(鸿蒙版)开发的第三篇 …

自然语言处理学习总结

目录 1、词表示 2、语言模型&#xff08;LM&#xff09; 3、常用学习网址 自然语言处理 1、词表示 词表示&#xff1a;自然语言中最基本的语言单位表示成机器理解的方式 方式一&#xff1a;词与词之间的相似度 方式二&#xff1a;词与词之间的关系 词义的表示方法&…

Linux 服务升级:MySQL 主从(半同步复制) 平滑升级

目录 一、实验 1.环境 2.Mysql-shell 检查工具兼容性 3.逻辑备份MySQL数据 4.备份MySQL 数据目录、安装目录、配置文件 5.MySQL 升级 6.master节点 使用systemd管理mysql8 7. slave1 节点升级 8. slave2 节点升级 9.半同步设置 二、问题 1.mysqldump备份报错 2.Inn…

FPGA控制AD7606_AD7606解读

目录 一、AD7606解读二、引脚说明三、时序图 一、AD7606解读 AD7606特点&#xff1a; 8通道同步采样模拟通道数为8分辨率&#xff1a;16bit&#xff0c;即最小采样的电压为5V/(2^16) 0,00007V&#xff0c;即数字量的1就代表模拟量的0,00007V&#xff0c;2代表0,00014V有效位数…