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

Flutter点击底部导航栏项打开Bottom Sheet的实现问题

解决方案

现有代码的问题

  • 你错误地将弹窗方法showBottomSheet()放到了页面组件数组中,Bottom Sheet是悬浮弹窗,不能作为Scaffold的body页面组件使用
  • 自定义的showBottomSheet方法仅内部声明了布局函数,没有调用Flutter官方提供的弹窗API,所以不会触发弹窗
  • 底部导航点击事件没有做分支判断,点击第四个选项时依然修改了当前页面下标,会导致body加载错误组件

修改步骤

  1. 移除页面数组中第四个无效的showBottomSheet()元素,只保留前三个业务页面
  2. 修改底部导航的onTap逻辑:点击下标为3的第四个选项时,不修改当前页面下标,直接调用弹窗方法
  3. 重写showBottomSheet方法,调用官方showModalBottomSheetAPI加载你写的弹窗布局

修改后的完整代码

import 'package:flutter/material.dart';

class _MyNavigationBarState extends State<MyNavigationBar> {
  int _currentTabIndex = 0;

  @override
  Widget build(BuildContext context) {
    // 仅保留三个业务页面即可
    final _kTabPages = <Widget>[
      Page1(),
      Page2(),
      Page3(),
    ];
    final _kBottmonNavBarItems = <BottomNavigationBarItem>[
      const BottomNavigationBarItem(icon: Icon(Icons.home), label: 'Home'),
      const BottomNavigationBarItem(icon: Icon(Icons.network_cell), label: 'Prices'),
      const BottomNavigationBarItem(icon: Icon(Icons.add_circle), label: 'Trade'),
      const BottomNavigationBarItem(icon: Icon(Icons.account_balance_wallet), label: 'Wallet'),
    ];
    final bottomNavBar = BottomNavigationBar(
      items: _kBottmonNavBarItems,
      currentIndex: _currentTabIndex,
      type: BottomNavigationBarType.fixed,
      onTap: (int index) {
        // 点击第四个选项时直接弹出底部弹窗,不切换当前页面
        if (index == 3) {
          showCustomBottomSheet(context);
          return;
        }
        // 前三个选项正常切换页面
        setState(() {
          _currentTabIndex = index;
        });
      },
    );
    return Scaffold(
      body: _kTabPages[_currentTabIndex],
      bottomNavigationBar: bottomNavBar,
    );
  }

  // 重写弹窗方法,调用官方Bottom Sheet API
  void showCustomBottomSheet(BuildContext context) {
    showModalBottomSheet(
      context: context,
      backgroundColor: Colors.transparent,
      isScrollControlled: true,
      builder: (BuildContext context) {
        return Container(
          height: 300,
          padding: const EdgeInsets.all(8.0),
          decoration: BoxDecoration(
            color: Colors.white,
            border: Border.all(color: Colors.blue, width: 2.0),
            borderRadius: BorderRadius.circular(8.0),
          ),
          child: ListView(
            children: <Widget>[
              const ListTile(title: Text('Bottom sheet')),
              const TextField(
                keyboardType: TextInputType.number,
                decoration: InputDecoration(
                  border: OutlineInputBorder(),
                  icon: Icon(Icons.attach_money),
                  labelText: 'Enter an integer',
                ),
              ),
              Container(
                alignment: Alignment.center,
                child: ElevatedButton.icon(
                  icon: const Icon(Icons.save),
                  label: const Text('Save and close'),
                  onPressed: () => Navigator.pop(context),
                ),
              )
            ],
          ),
        );
      }
    );
  }
}

注意事项

  • 弹窗布局要设置白色背景,否则会出现透明背景问题
  • isScrollControlled参数设为true可适配弹窗内输入框弹出时的布局偏移
  • 不需要保留之前的长度校验assert逻辑,现在页面数组长度和导航项长度不需要完全一致

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 12:09:01