You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在横屏模式下将Flutter BottomNavigationBar放置在屏幕左侧

预期视图

预期视图


实现方案

该需求可以直接实现,无需额外第三方依赖,推荐优先使用Flutter官方提供的NavigationRail组件配合横竖屏检测实现,这是最适配原生设计规范的方案。

具体实现逻辑如下:

  • 使用OrientationBuilder监听屏幕横竖屏状态变化
  • 竖屏状态下渲染常规底部BottomNavigationBar
  • 横屏状态下隐藏底部导航,在屏幕左侧渲染NavigationRail侧边导航栏

示例代码:

import 'package:flutter/material.dart';

void main() => runApp(const MyApp());

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: '横竖屏导航切换 demo',
      theme: ThemeData(primarySwatch: Colors.blue),
      home: const NavDemoPage(),
    );
  }
}

class NavDemoPage extends StatefulWidget {
  const NavDemoPage({super.key});

  @override
  State<NavDemoPage> createState() => _NavDemoPageState();
}

class _NavDemoPageState extends State<NavDemoPage> {
  int _selectedIndex = 0;

  // 页面列表
  final List<Widget> _pages = const [
    Center(child: Text('首页')),
    Center(child: Text('分类')),
    Center(child: Text('我的')),
  ];

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('导航切换演示')),
      body: OrientationBuilder(
        builder: (context, orientation) {
          // 横屏状态:左侧导航栏+右侧内容
          if (orientation == Orientation.landscape) {
            return Row(
              children: [
                NavigationRail(
                  selectedIndex: _selectedIndex,
                  onDestinationSelected: (index) {
                    setState(() => _selectedIndex = index);
                  },
                  labelType: NavigationRailLabelType.all,
                  destinations: const [
                    NavigationRailDestination(
                      icon: Icon(Icons.home),
                      label: Text('首页'),
                    ),
                    NavigationRailDestination(
                      icon: Icon(Icons.category),
                      label: Text('分类'),
                    ),
                    NavigationRailDestination(
                      icon: Icon(Icons.person),
                      label: Text('我的'),
                    ),
                  ],
                ),
                const VerticalDivider(thickness: 1, width: 1),
                // 内容区域
                Expanded(child: _pages[_selectedIndex]),
              ],
            );
          }
          // 竖屏状态:正常内容区域,底部放导航栏
          else {
            return _pages[_selectedIndex];
          }
        },
      ),
      // 竖屏才显示底部导航栏
      bottomNavigationBar: OrientationBuilder(
        builder: (context, orientation) {
          return orientation == Orientation.portrait
              ? BottomNavigationBar(
                  currentIndex: _selectedIndex,
                  onTap: (index) {
                    setState(() => _selectedIndex = index);
                  },
                  items: const [
                    BottomNavigationBarItem(icon: Icon(Icons.home), label: '首页'),
                    BottomNavigationBarItem(icon: Icon(Icons.category), label: '分类'),
                    BottomNavigationBarItem(icon: Icon(Icons.person), label: '我的'),
                  ],
                )
              : const SizedBox.shrink();
        },
      ),
    );
  }
}

替代方案

如果你一定要复用原有BottomNavigationBar的样式而不想用NavigationRail,也可以直接在横屏状态的Row组件左侧直接放入改造后的BottomNavigationBar,将其type设置为BottomNavigationBarType.fixed,同时包裹在RotatedBox或者调整宽度适配竖排展示即可,不过这种方案需要自行适配点击事件和样式,兼容性不如官方NavigationRail。


内容的提问来源于stack exchange,提问作者Chanaka

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.05 23:48:02