欢迎访问 生活随笔!

生活随笔

当前位置: 首页 > 编程资源 > 编程问答 >内容正文

编程问答

在 Flutter 中使用 NavigationRail 和 BottomNavigationBar

发布时间:2025/3/19 编程问答 42 豆豆
生活随笔 收集整理的这篇文章主要介绍了 在 Flutter 中使用 NavigationRail 和 BottomNavigationBar 小编觉得挺不错的,现在分享给大家,帮大家做个参考.

在 Flutter 中使用 NavigationRail 和 BottomNavigationBar

作者:坚果

公众号:“大前端之旅”

华为云享专家,InfoQ签约作者,阿里云专家博主,51CTO博客首席体验官,开源项目GVA成员之一,专注于大前端技术的分享,包括Flutter,鸿蒙,小程序,安卓,VUE,JavaScript等。

本文将向您展示如何使用NavigationRailBottomNavigationBar在 Flutter 中创建****自适应布局。我们将浏览一下这个概念,然后通过一个完整的例子来在实践中应用这个概念。

NavigationRail小部件用于创建位于应用左侧或右侧的“垂直标签栏”。它非常适合平板电脑、笔记本电脑、电视等宽屏设备。它通常包含多个视图,让用户可以轻松地在不同视图之间切换。

BottomNavigationBar部件用于创建非常适合智能手机的底部标签栏。它由多个选项卡组成,让用户可以轻松地在视图之间导航。

我们可以使用NavigationRailBottomNavigationBar来构建现代自适应布局。当屏幕很大时,我们显示NavigationRail,当屏幕较小时,我们显示BottomNavigationBar。一次只出现其中一个。要检测屏幕宽度,我们可以使用:

MediaQuery.of(context).size.width

这个例子

应用预览

我们要构建的应用程序有一个导航栏、一个底部标签栏和 4 个不同的视图:主页、Feed、收藏夹和设置。每个视图都与底部标签栏的一个标签和导航栏的一个项目相连。

  • 如果屏幕宽度小于 640 像素,则将呈现底部标签栏,而不会显示左侧导航栏。
  • 如果屏幕宽度等于或大于 640 像素,则不会呈现底部标签栏,而会显示左侧导航栏。

以下是它的工作原理:

截图

代码

这是生成上述应用程序的完整代码(带有解释):

// main.dart import 'package:flutter/material.dart';void main() {runApp(const MyApp()); }class MyApp extends StatelessWidget {const MyApp({Key? key}) : super(key: key);@overrideWidget build(BuildContext context) {return MaterialApp(// Remove the debug bannerdebugShowCheckedModeBanner: false,title: '大前端之旅',theme: ThemeData(primarySwatch: Colors.indigo),home: const HomeScreen());} }class HomeScreen extends StatefulWidget {const HomeScreen({Key? key}) : super(key: key);@override_HomeScreenState createState() => _HomeScreenState(); }class _HomeScreenState extends State<HomeScreen> {// The contents of views// Only the content associated with the selected tab is displayed on the screenfinal List<Widget> _mainContents = [// Content for Home tabContainer(color: Colors.yellow.shade100,alignment: Alignment.center,child: const Text('Home',style: TextStyle(fontSize: 40),),),// Content for Feed tabContainer(color: Colors.purple.shade100,alignment: Alignment.center,child: const Text('Feed',style: TextStyle(fontSize: 40),),),// Content for Favorites tabContainer(color: Colors.red.shade100,alignment: Alignment.center,child: const Text('Favorites',style: TextStyle(fontSize: 40),),),// Content for Settings tabContainer(color: Colors.pink.shade300,alignment: Alignment.center,child: const Text('Settings',style: TextStyle(fontSize: 40),),)];// The index of the selected tab// In the beginning, the Home tab is selectedint _selectedIndex = 0;@overrideWidget build(BuildContext context) {return Scaffold(appBar: AppBar(title: const Text('大前端之旅'),),// Show the bottom tab bar if screen width < 640bottomNavigationBar: MediaQuery.of(context).size.width < 640? BottomNavigationBar(currentIndex: _selectedIndex,unselectedItemColor: Colors.grey,selectedItemColor: Colors.indigoAccent,// called when one tab is selectedonTap: (int index) {setState(() {_selectedIndex = index;});},// bottom tab itemsitems: const [BottomNavigationBarItem(icon: Icon(Icons.home), label: 'Home'),BottomNavigationBarItem(icon: Icon(Icons.feed), label: 'Feed'),BottomNavigationBarItem(icon: Icon(Icons.favorite), label: 'Favorites'),BottomNavigationBarItem(icon: Icon(Icons.settings), label: 'Settings')]): null,body: Row(mainAxisSize: MainAxisSize.max,children: [// Show the navigaiton rail if screen width >= 640if (MediaQuery.of(context).size.width >= 640)NavigationRail(minWidth: 55.0,selectedIndex: _selectedIndex,// Called when one tab is selectedonDestinationSelected: (int index) {setState(() {_selectedIndex = index;});},labelType: NavigationRailLabelType.all,selectedLabelTextStyle: const TextStyle(color: Colors.amber,),leading: Column(children: const [SizedBox(height: 8,),CircleAvatar(radius: 20,child: Icon(Icons.person),),],),unselectedLabelTextStyle: const TextStyle(),// navigation rail itemsdestinations: const [NavigationRailDestination(icon: Icon(Icons.home), label: Text('Home')),NavigationRailDestination(icon: Icon(Icons.feed), label: Text('Feed')),NavigationRailDestination(icon: Icon(Icons.favorite), label: Text('Favorites')),NavigationRailDestination(icon: Icon(Icons.settings), label: Text('Settings')),],),// Main content// This part is always shown// You will see it on both small and wide screenExpanded(child: _mainContents[_selectedIndex]),],),);} }

构造函数和引用

NavigationRail 构造函数:

NavigationRail({Key? key, Color? backgroundColor, bool extended = false, Widget? leading, Widget? trailing, required List<NavigationRailDestination> destinations, required int selectedIndex, ValueChanged<int>? onDestinationSelected, double? elevation, double? groupAlignment, NavigationRailLabelType? labelType, TextStyle? unselectedLabelTextStyle, TextStyle? selectedLabelTextStyle, IconThemeData? unselectedIconTheme, IconThemeData? selectedIconTheme, double? minWidth, double? minExtendedWidth, bool? useIndicator, Color? indicatorColor })

BottomNavigationBar 构造函数:

BottomNavigationBar({Key? key, required List<BottomNavigationBarItem> items, ValueChanged<int>? onTap, int currentIndex = 0, double? elevation, BottomNavigationBarType? type, Color? fixedColor, Color? backgroundColor, double iconSize = 24.0, Color? selectedItemColor, Color? unselectedItemColor, IconThemeData? selectedIconTheme, IconThemeData? unselectedIconTheme, double selectedFontSize = 14.0, double unselectedFontSize = 12.0, TextStyle? selectedLabelStyle, TextStyle? unselectedLabelStyle, bool? showSelectedLabels, bool? showUnselectedLabels, MouseCursor? mouseCursor, bool? enableFeedback, BottomNavigationBarLandscapeLayout? landscapeLayout })

参考:

  • navigation:设计(material.io)
  • NavigationRail 类(flutter.dev)
  • NavigationRailDestination类 (flutter.dev)
  • BottomNavigationBar 类(flutter.dev)

后记

您已经学习了一种使用 NavigationRail 和 BottomNavigationBar 创建现代自适应用户界面的简单但有效的技术。考虑到这些知识,您可以为从智能手机到平板电脑和笔记本电脑的各种设备构建更直观、更有吸引力的应用程序。因此,您的应用程序将获得越来越多的用户,并有更大的成功机会。

总结

以上是生活随笔为你收集整理的在 Flutter 中使用 NavigationRail 和 BottomNavigationBar的全部内容,希望文章能够帮你解决所遇到的问题。

如果觉得生活随笔网站内容还不错,欢迎将生活随笔推荐给好友。