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

​​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.mzph.cn/news/757004.shtml

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

相关文章

MacOS Xcode 使用LLDB调试Qt的 QString

环境&#xff1a; MacOS&#xff1a; 14.3Xcode&#xff1a; Version 15.0Qt&#xff1a;Qt 6.5.3 前言 Xcode 中显示 预览 QString 特别不方便, 而Qt官方的 lldb 脚本debugger/lldbbridge.py一直加载失败&#xff0c;其他第三方的脚本都 不兼容当前的 环境。所以自己研究写…

游戏反云手机检测方案

游戏风险环境&#xff0c;是指独立于原有设备或破坏设备原有系统的环境。常见的游戏风险环境有&#xff1a;云手机、虚拟机、虚拟框架、iOS越狱、安卓设备root等。 这类风险环境可以为游戏外挂、破解提供所需的高级别设备权限&#xff0c;当游戏处于这些风险环境下&#xff0c…

CCIE-04-Layer2_WAN_TS

目录 实验条件网络拓朴 路由器配置开始排错&#xff0c; 要求R11可以访问R17的telnet检查R12和R11的e0/0口&#xff0c;有发现检查R17和R12的S4/0口&#xff0c; 有发现ping R17环回口地址&#xff0c;发现不通telnet R17环回口IP 实验条件 网络拓朴 路由器配置 R11 4组以太网…

25.6 MySQL 子查询

1. 子查询 子查询(Subquery): 是SQL查询语句中的一个重要概念, 它允许在一个查询语句(主查询)中嵌套另一个查询语句(子查询). 这意味着一个查询可以作为另一个查询的输入或条件, 子查询可以出现在SQL语句的多个位置, 例如SELECT, FROM, WHERE等子句中.子查询通常用于以下几种情…

网络安全的几个关键领域

网络安全是一个复杂且多维度的领域&#xff0c;涵盖了多个关键领域&#xff0c;涉及到信息保护、网络防护、应用安全、用户教育以及物理安全等多个方面。这些关键领域相互交织&#xff0c;共同构成了网络安全这一宏大且细致入微的领域。 今天德迅云安全就分享下网络安全的几个…

Covalent Network借助大规模的历史Web3数据集,推动人工智能发展

人工智能在众多领域中增强了区块链的实用性&#xff0c;反之亦然&#xff0c;区块链确保了 AI 模型所使用的数据的来源和质量。人工智能带来的生产力提升&#xff0c;将与区块链系统固有的安全性和透明度融合。 Covalent Network&#xff08;CQT&#xff09;正位于这两项互补技…

Docker 学习笔记

Play With Docker一个免费使用的基于web界面的Docker环境 常用docker命令 可使用docker COMMAND --help查看命令的用法 Docker镜像相关 1、docker image pull&#xff1a;用于下载镜像&#xff0c;镜像从远程镜像仓库服务的仓库中下载&#xff0c;默认从Docker Hub的仓库中拉…

JS+CSS3点击粒子烟花动画js特效

JSCSS3点击粒子烟花动画js特效 JSCSS3点击粒子烟花动画js特效

idea import的maven类报红

idea 报红/显示红色的原因 一般报红&#xff0c;显示红色&#xff0c;是因为 idea 在此路径下&#xff0c;找不到这个类。 找到是哪个 jar 包的类导致 idea 报红 点击报红的路径的上一层&#xff0c;进入jar 包。比如&#xff1a; import com.aaa.bbb.ccc.DddDto;这个 impo…

TikTok云手机是什么原理?

随着社交媒体的快速发展和普及&#xff0c;TikTok已成为全球最受欢迎的短视频平台之一&#xff0c;吸引了数以亿计的用户。在TikTok上&#xff0c;许多用户和内容创作者都希望能够更灵活地管理和运营多个账号&#xff0c;这就需要借助云手机技术。那么&#xff0c;TikTok云手机…

windows跳板机配置(端口转发)

目录 前言操作步骤端口防火墙开放测试参考 前言 跳板机一般用于异构网络间的中转站&#xff0c;比如对方在防火墙上只给你开放了一台服务器的权限&#xff0c;你无法访问对方局域网的其它主机&#xff0c;但你能访问的这台服务器则有权限访问其它主机。那么这台服务器就可以作…

基于python失物招领系统-安卓-flask-django-nodejs-php

随着现在网络的快速发展&#xff0c;网络的应用在各行各业当中&#xff0c;利用网络来做这个失物招领的网站&#xff0c;随之就产生了“失物招领 ”&#xff0c;这样用户就可以利用平台来发布信息。 对于本失物招领 的设计来说&#xff0c; 它是应用mysql数据库、安卓等技术动…

【YOLOv5改进系列(1)】高效涨点----使用EIoU、Alpha-IoU、SIoU、Focal-EIOU替换CIou

改进IOU损失函数 &#x1f680;&#x1f680;&#x1f680;前言一、1️⃣ 如何添加损失函数1.1 &#x1f393; 修改bbox_iou函数1.2 ✨修改__call__中iou函数 二、2️⃣替换EIOU三、3️⃣替换SIoU四、4️⃣替换Alpha-IoU五、5️⃣替换Focal-EIOU六、6️⃣ 替换后的实验结果 &a…

Scala--03--变量和数据类型

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 变量和数据类型1.注释2 变量和常量&#xff08;重点&#xff09;3 标识符的命名规范4 字符串输出5.IO 输入 输出键盘输入读写文件 IO 6.数据类型&#xff08;重点&a…

3D开发工具HOOPS如何助力3D项目实现扩展现实技术?

在当今数字化时代&#xff0c;扩展现实&#xff08;Augmented Reality&#xff0c;AR&#xff09;技术的应用已经逐渐深入到各行各业&#xff0c;为用户带来了前所未有的沉浸式体验。而在实现这种技术的开发过程中&#xff0c;HOOPS技术的运用无疑是一种强大的助力。HOOPS是一种…

element-ui出的treeselect下拉树组件基本使用,以及只能选择叶子节点的功能,给节点添加按钮操作

element-ui出的treeselect下拉树组件基本使用&#xff1a;Vue通用下拉树组件riophae/vue-treeselect的使用-CSDN博客 vue-treeselect 问题合集、好用的树形下拉组件&#xff08;vue-treeselect的使用、相关问题解决方案&#xff09;-CSDN博客 需求1&#xff1a;treeselect下拉…

力扣Lc18--- 168. Excel表列名称(java版)-2024年3月19日

1.题目描述 2.知识点 注1&#xff1a;StringBuilder 对象的 insert() 方法用于在字符串的指定位置插入字符或字符序列。这里的第一个参数是插入位置的索引&#xff0c;而第二个参数是要插入的字符或字符序列。 public class InsertExample {public static void main(String[…

Filter and Listener and AJAX and JSON

一、Filter Filter 表示过滤器&#xff0c;是 JavaWeb 三大组件(Servlet、Filter、Listener)之一。过滤器可以把对资源的请求拦截下来&#xff0c;从而实现一些特殊的功能。&#xff08;拦截指定资源&#xff09; 正常情况下&#xff0c;浏览器可以访问服务器上的所有的资源&…

瑞_Redis_短信登录

文章目录 项目介绍1 短信登录1.1 项目准备1.1.1 导入SQL1.1.2 导入后端项目1.1.3 导入前端项目 1.2 基于Session实现登录流程1.2.1 功能流程介绍1.2.1.1 发送短信验证码1.2.1.2 短信验证码登录、注册1.2.1.3 校验登录状态 1.2.2 实现发送短信验证码功能1.2.2.1 页面流程1.2.2.2…

【保姆级】前端使用node.js基础教程

文章目录 安装和版本管理&#xff1a;npm 命令&#xff08;Node 包管理器&#xff09;&#xff1a;运行 Node.js 脚本&#xff1a;调试和开发工具&#xff1a;其他常用命令&#xff1a;模块管理&#xff1a;包管理&#xff1a;调试工具&#xff1a;异步编程和包管理&#xff1a…