当前位置: 首页 > article >正文

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

前言

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

  • 当宽度>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: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;
 
  @override
  State<LeftNavigationBar> createState() => _LeftNavigationBarState();
}
 
class _LeftNavigationBarState extends State<LeftNavigationBar> {
  @override
  Widget 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;
 
  @override
  State<LeftNavigationBarItemWidget> createState() =>
      _LeftNavigationBarItemWidgetState();
}
 
class _LeftNavigationBarItemWidgetState
    extends 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);
  @override
  Widget 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;
 
  @override
  Widget 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 {
  //菜单栏对应的Id
  final 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.kler.cn/a/395902.html

相关文章:

  • maven的optional选项说明以及具体应用
  • 【Linux】Linux 权限的理解
  • 群控系统服务端开发模式-应用开发-前端登录接口开发
  • 第12章 系统部署
  • 如何在手机上完整下载B站视频并保存到相册?
  • 计算机网络 (1)互联网的组成
  • 使用机器学习优化数据库查询性能
  • FastGPT部署通义千问Qwen和智谱glm模型|OneAPI配置免费的第三方API
  • 基于集成Whisper 与 Pepper-GPT改进人机交互体验并实现顺畅通信
  • Git之国内项目托管平台
  • 物联网低功耗广域网LoRa开发(二):LoRa开发环境搭建及驱动移植
  • CSS基础知识01
  • 论文 | On Second Thought, Let’s Not Think Step by Step!
  • 【澜舟科技-注册/登录安全分析报告】
  • 蓝桥杯每日真题 - 第12天
  • 刷别的学校oj—河工大oj1073-1099
  • linux 下调试 bmp280 气压传感器
  • jmeter常用配置元件介绍总结之逻辑控制器
  • 【笔记】关于git和GitHub和git bash
  • Neo4j Desktop 和 Neo4j Community Edition 区别
  • CAN编程示例之socket CAN
  • 人工智能大模型即服务时代:在网络安全中的应用
  • 使用runtime/pprof包进行Go程序性能调优的实战教程
  • 博物馆实景复刻:开启沉浸式文化体验的新篇章
  • HMSC联合物种分布模型在群落生态学中的贝叶斯统计分析
  • 性能测试类型