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,});
}