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

server/2024/11/19 5:36:34/
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/server/143093.html

相关文章

【ORACLE战报】2024年10月OCP考试战报

原创 厦门微思网络 微思 | 新班预告&#xff1a; 所有的收获都是默默耕耘的成果 2024.10月【最新考试成绩出炉】 来吧&#xff0c;展示 &#xff08;以下为部分学员成绩单&#xff09; &#xff08;部分学员证书&#xff09; 往期考试战报回顾&#xff1a; 【ORACLE战报】…

解析“ChatGPT网络错误”:从网络专线到IP地址的根源与解决方案

在日常使用 ChatGPT 或其他在线服务时&#xff0c;偶尔会遇到“网络错误”的提示&#xff0c;尤其是在请求响应时间较长或出现连接中断的情况下。这种错误常常让用户感到困扰&#xff0c;但实际上&#xff0c;网络错误的发生并不总是因为服务端出现问题&#xff0c;很多时候&am…

FFmpeg 4.3 音视频-多路H265监控录放C++开发十三.2:avpacket中包含多个 NALU如何解析头部分析

前提&#xff1a; 注意的是&#xff1a;我们这里是从avframe转换成avpacket 后&#xff0c;从avpacket中查看NALU。 在实际开发中&#xff0c;我们有可能是从摄像头中拿到 RGB 或者 PCM&#xff0c;然后将pcm打包成avframe&#xff0c;然后将avframe转换成avpacket&#xff0…

【计算机网络】TCP协议特点1

TCP/IP协议头 TCP/IP族是一组网络通信协议的集合&#xff0c;一个分层、多协议的通信体系&#xff0c;它是互联网的基础通信协议。这个协议族定义了电子设备如何连入互联网&#xff0c;以及数据如何在它们之间传输。TCP/IP 协议族通常被分为四层&#xff0c;从下到上分别是数据…

移门缓冲支架:减少噪音,提升生活质量

移门缓冲支架不仅是一个简单的五金配件&#xff0c;更是提升家居生活质量的有效工具。通过减少门关闭时的噪音&#xff0c;移门缓冲支架能够创造一个安静、舒适的生活环境。以下是移门缓冲支架在减少噪音、提升生活质量方面的详细解析&#xff1a; 1. 显著降低关门噪音问题&…

谷歌浏览器的自动翻译功能如何开启

在当今全球化的网络环境中&#xff0c;能够流畅地浏览不同语言的网页是至关重要的。谷歌浏览器&#xff08;Google Chrome&#xff09;提供了一项强大的自动翻译功能&#xff0c;可以帮助用户轻松跨越语言障碍。本文将详细介绍如何开启和使用谷歌浏览器的自动翻译功能&#xff…

ES6进阶知识二

一、promise方法的案例 Promise对象通过new Promise()语法创建&#xff0c;它接受一个函数作为参数&#xff0c;该函数接受两个参数&#xff1a;resolve和reject。resolve表示异步操作成功&#xff0c;reject表示异步操作失败。 案例&#xff1a;异步加载图片 const loadIma…

go语言中的反射机制(基础)

反射基本介绍 反射可以在运行时动态获取变量的各种信息&#xff0c;比如变量的类型(type)&#xff0c;类别(kind)如果是结构体变量&#xff0c;还可以获取到结构体本身的信息(包括结构体的字段、方法)通过反射&#xff0c;可以修改变量的值&#xff0c;可以调用关联的方法。使…