Flutter-左侧导航栏跟随窗口的宽变化

news/2024/11/19 3:42:25/
htmledit_views">

前言

现在有一个需求:左侧导航栏跟随窗口的宽度变化而变化

  • 当宽度>1000时,左侧导航栏全部展示,
  • 1000>宽度>500时,左侧导航栏只展示图标,
  • 500>宽度时,左侧导航栏消失,顶部出现菜单选择图标,点击后可以选择菜单内容

我们要实现上面的功能就需要使用到屏幕的自适应功能,我这里主要用到的就是LayoutBuilder这个组件

操作流程

  • 获取屏幕的宽度
  • 当屏幕小于指定值时,左侧导航栏展示一个宽高都为0的组件,反之展示全部内容
  • 我的左侧导航栏中的每一项格式相同,因此我将之抽离了出来并命名为LeftNavigationBarItemWidget。当宽度小于一定范围时,LeftNavigationBarItemWidget只展示图标,反之展示图标和文本
  • 通过上面的3步就实现了左侧导航栏的变化

具体步骤

1.在左侧导航栏的代码中获取屏幕的宽度

Size screenSize = MediaQuery.of(context).size;
double winWidth = screenSize.width;

2.使用LayoutBuilder组件判断当窗口屏幕小于指定值是展示空内容,反之展示

LayoutBuilder(builder: (p0, p1) {if (winWidth < leftNavigationBarSelfValue1) {return Container();} else {return Container(height: double.infinity,width: winWidth < leftNavigationBarSelfValue ? 60 : 280,color: Colors.white,padding: const EdgeInsets.only(top: 20),child: SingleChildScrollView(child: Column(children: MenuValue.LeftNavigationBarItems.map((e) => LeftNavigationBarItemWidget(item: e,active: widget.selectRoute == e.route,)).toList(),),),);}},);

3.当窗口小于一定值后左侧导航栏的每一项(LeftNavigationBarItemWidget组件),就只展示图标,不展示文本内容

LayoutBuilder(builder: (p0, p1) {if (winWidth < leftNavigationBarSelfValue) {return Center(child: Icon(Icons.wallet,color: active ? activeTextColor : initIconColor,),);} else {return OriginalSizeItemWidget(active: active,activeTextColor: activeTextColor,initIconColor: initIconColor,widget: widget,initTextColor: initTextColor);}},)

至此就实现了左侧导航栏跟随窗口宽度改变而改变

全部代码

import 'package:html" title=flutter>flutter/material.dart';
import 'package:get/get.dart';
import 'package:my_app/common/store/limits_of_authority.dart';
import 'package:my_app/common/value/menu.dart';
import 'package:my_app/common/value/self_adaption_value.dart';
import 'package:provider/provider.dart';import '../../../routes/names.dart';class LeftNavigationBar extends StatefulWidget {const LeftNavigationBar({super.key,required this.selectRoute,});final String selectRoute;@overrideState<LeftNavigationBar> createState() => _LeftNavigationBarState();
}class _LeftNavigationBarState extends State<LeftNavigationBar> {@overrideWidget build(BuildContext context) {Size screenSize = MediaQuery.of(context).size;double winWidth = screenSize.width;return LayoutBuilder(builder: (p0, p1) {if (winWidth < leftNavigationBarSelfValue1) {return Container();} else {return Container(height: double.infinity,width: winWidth < leftNavigationBarSelfValue ? 60 : 280,color: Colors.white,padding: const EdgeInsets.only(top: 20),child: SingleChildScrollView(child: Column(children: MenuValue.LeftNavigationBarItems.map((e) => LeftNavigationBarItemWidget(item: e,active: widget.selectRoute == e.route,)).toList(),),),);}},);}
}class LeftNavigationBarItemWidget extends StatefulWidget {const LeftNavigationBarItemWidget({super.key,required this.active,required this.item,this.isHeard = false,});final bool active;final LeftNavigationBarItem item;final bool? isHeard;@overrideState<LeftNavigationBarItemWidget> createState() =>_LeftNavigationBarItemWidgetState();
}class _LeftNavigationBarItemWidgetStateextends State<LeftNavigationBarItemWidget> {bool _hovering = false;final Color initBgcColor = Colors.white;final Color activeBgcColor = const Color.fromRGBO(229, 240, 255, 1);final Color initTextColor = const Color.fromRGBO(40, 40, 40, 1);final Color activeTextColor = const Color.fromRGBO(0, 111, 255, 1);final Color initIconColor = const Color.fromRGBO(167, 185, 210, 1);@overrideWidget build(BuildContext context) {bool active = widget.active || _hovering;Size screenSize = MediaQuery.of(context).size;double winWidth = screenSize.width;return Container(width: double.infinity,height: 60,color: active ? activeBgcColor : initBgcColor,// padding: ,child: InkWell(onTap: () {Provider.of<LimitsOfAuthorityStore>(context, listen: false).selectMenuNum = widget.item.id;Get.offNamed("/${widget.item.route}");},onHover: (value) {setState(() {_hovering = value;});},child: !widget.isHeard!? LayoutBuilder(builder: (p0, p1) {if (winWidth < leftNavigationBarSelfValue) {return Center(child: Icon(Icons.wallet,color: active ? activeTextColor : initIconColor,),);} else {return OriginalSizeItemWidget(active: active,activeTextColor: activeTextColor,initIconColor: initIconColor,widget: widget,initTextColor: initTextColor);}},): OriginalSizeItemWidget(active: active,activeTextColor: activeTextColor,initIconColor: initIconColor,widget: widget,initTextColor: initTextColor),),);}
}class OriginalSizeItemWidget extends StatelessWidget {const OriginalSizeItemWidget({super.key,required this.active,required this.activeTextColor,required this.initIconColor,required this.widget,required this.initTextColor,});final bool active;final Color activeTextColor;final Color initIconColor;final LeftNavigationBarItemWidget widget;final Color initTextColor;@overrideWidget build(BuildContext context) {return Row(mainAxisSize: MainAxisSize.min,children: [const SizedBox(width: 32,),Icon(Icons.wallet,color: active ? activeTextColor : initIconColor,),const SizedBox(width: 8,),Text(widget.item.label,style: TextStyle(color: active ? activeTextColor : initTextColor,),),],);}
}class LeftNavigationBarItem {//菜单栏对应的Idfinal int id;//菜单栏的图标final IconData icon;//菜单栏的文字final String label;final String route;const LeftNavigationBarItem({required this.icon,required this.label,required this.id,required this.route,});
}


http://www.ppmy.cn/news/1548141.html

相关文章

Prometheus面试内容整理-场景应用和故障排查

在实际使用 Prometheus 的过程中,场景应用和故障排查是确保监控系统正常运行和及时解决问题的关键部分。通过在特定的应用场景中合理地部署和配置 Prometheus,可以高效监控系统的各个组件。而在出现问题时,正确的故障排查流程则有助于快速定位并解决问题。以下是一些 Promet…

Mysql中REPLACE INTO详解及和INSERT INTO的区别

前言 我们在进行数据库操作的时候&#xff0c;经常会遇到这样的场景&#xff1a; 首先判断数据是否存在&#xff1b;如果不存在&#xff0c;则插入&#xff1b;如果存在&#xff0c;则更新。 博主之前是是Java来进行逻辑判断&#xff0c;例如&#xff1a; 看起来似乎也很简洁…

QDataStream

本文来自&#xff1a; 智谱清言 Qt助手 ------ QDataStream 是 Qt 框架中的一个类&#xff0c;用于序列化和反序列化二进制数据。它允许你将基本数据类型&#xff08;如 int、double、QString 等&#xff09;以及 Qt 容器类&#xff08;如 QList、QMap 等&#xff09;写入到…

动态IP代理技术详解与实现

目录 一、动态IP代理技术概述 二、动态IP代理技术的原理 代理服务器中转&#xff1a; IP地址动态更换&#xff1a; 协议支持&#xff1a; 智能调度机制&#xff1a; 三、动态IP代理的实现方法 基于HTTP代理的实现&#xff1a; 正向代理&#xff1a; 反向代理&#xf…

用 Python 从零开始创建神经网络(八):梯度、偏导数和链式法则

梯度、偏导数和链式法则 引言1. 偏导数2. 和的偏导数3. 乘法的偏导数4. Max 的偏导数5. 梯度&#xff08;The Gradient&#xff09;6. 链式法则&#xff08;The Chain Rule&#xff09; 引言 在我们继续编写我们的神经网络代码之前&#xff0c;最后两个需要解决的难题是梯度和…

大语言模型通用能力排行榜(2024年11月8日更新)

数据来源SuperCLUE 榜单数据为通用能力排行榜 排名 模型名称 机构 总分 理科 文科 Hard 使用方式 发布日期 - o1-preview OpenAI 75.85 86.07 76.6 64.89 API 2024年11月8日 - Claude 3.5 Sonnet&#xff08;20241022&#xff09; Anthropic 70.88 82.4…

树莓派(Raspberry Pi)picotool

树莓派&#xff08;Raspberry Pi&#xff09;picotool 安装直接安装从源码安装工具介绍显示信息保存程序二进制信息基本信息引脚完整信息 链接 安装 直接安装 在archlinux上&#xff0c;使用yay直接安装 yay -S picotool从源码安装 安装libusb sudo pacman -S libusb下载 …

号卡分销系统,号卡系统,物联网卡系统源码安装教程

号卡分销系统&#xff0c;号卡系统&#xff0c;物联网卡系统&#xff0c;&#xff0c;实现的高性能(PHP协程、PHP微服务)、高灵活性、前后端分离(后台)&#xff0c;PHP 持久化框架&#xff0c;助力管理系统敏捷开发&#xff0c;长期持续更新中。 主要特性 基于Auth验证的权限…