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

如何实现滚动时隐藏底部导航栏?(基于persistent_bottom_nav_bar)

问题解答

问题1:如何隐藏底部导航栏?

使用persistent_bottom_nav_bar包时,可通过控制hideNavigationBar参数切换导航栏的显示/隐藏状态,结合状态管理就能实现动态隐藏。

问题2:监听ListView滚动并动态隐藏底部导航栏

要实现子页面滚动联动父页面导航栏隐藏,需通过滚动控制器监听+跨页面状态传递实现,具体步骤如下:

步骤1:改造bottom_nav_bar.dart,添加状态控制

将原代码改为StatefulWidget,新增状态变量控制导航栏显示,并提供回调方法供子页面触发状态更新:

import 'package:flutter/material.dart';
import 'package:persistent_bottom_nav_bar/persistent_bottom_nav_bar.dart';
import 'package:sizer/sizer.dart';
import 'connection_view.dart';

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

  @override
  State<BottomNavBar> createState() => _BottomNavBarState();
}

class _BottomNavBarState extends State<BottomNavBar> {
  bool _isNavBarVisible = true;

  // 供子页面调用,更新导航栏显示状态
  void updateNavBarVisibility(bool visible) {
    setState(() {
      _isNavBarVisible = visible;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Sizer(builder: ((context, orientation, deviceType) {
      return Scaffold(
        body: PersistentTabView(
          context,
          screens: [
            // 将状态更新方法传递给子页面
            ClientConnection(updateNavBar: updateNavBarVisibility),
            const ClientDiscover(),
            const ClientDiscover(),
            const ClientDiscover(),
          ],
          items: _navBarsItems(),
          navBarStyle: NavBarStyle.style1,
          bottomScreenMargin: 0,
          navBarHeight: 60,
          padding: const NavBarPadding.all(5),
          margin: const EdgeInsets.only(
            bottom: 15,
            left: 20,
            right: 20,
          ),
          decoration: const NavBarDecoration(
            borderRadius: BorderRadius.only(
              topLeft: Radius.circular(30),
              topRight: Radius.circular(30),
            ),
            boxShadow: [
              BoxShadow(
                color: Colors.grey,
                blurRadius: 5,
                offset: Offset(2, 2),
              )
            ],
          ),
          // 核心:控制导航栏显示隐藏
          hideNavigationBar: !_isNavBarVisible,
          // 添加过渡动画提升体验
          navBarCurve: Curves.easeInOut,
        ),
      );
    }));
  }

  List<PersistentBottomNavBarItem> _navBarsItems() {
    return [
      PersistentBottomNavBarItem(
        icon: SvgPicture.asset(
          'assets/active-connection-icon.svg',
          width: 5.w,
        ),
        title: ("CONNECTIONS"),
        inactiveIcon: SvgPicture.asset(
          'assets/inactive-connection-icon.svg',
          width: 5.w,
        ),
      ),
      PersistentBottomNavBarItem(
        icon: SvgPicture.asset(
          'assets/active-discover-icon.svg',
          width: 5.w,
        ),
        title: ("DISCOVER"),
        inactiveIcon: SvgPicture.asset(
          'assets/inactive-discover-icon.svg',
          width: 5.w,
        ),
      ),
      PersistentBottomNavBarItem(
        icon: SvgPicture.asset(
          'assets/active-profile-icon.svg',
          width: 5.w,
        ),
        title: ("PROFILE"),
        inactiveIcon: SvgPicture.asset(
          'assets/inactive-profile-icon.svg',
          width: 5.w,
        ),
      ),
      PersistentBottomNavBarItem(
        icon: SvgPicture.asset(
          'assets/active-notification-icon.svg',
          width: 5.w,
        ),
        title: ("NOTIFICATIONS"),
        inactiveIcon: SvgPicture.asset(
          'assets/inactive-notification-icon.svg',
          width: 5.w,
        ),
      ),
    ];
  }
}

步骤2:改造connection_view.dart,添加滚动监听

在子页面中通过ScrollController监听滚动方向,根据偏移量判断是否触发导航栏隐藏:

import 'package:flutter/material.dart';
import 'package:sizer/sizer.dart';

// 定义回调类型,用于传递状态更新
typedef UpdateNavBarCallback = void Function(bool isVisible);

class ClientConnection extends StatefulWidget {
  final UpdateNavBarCallback updateNavBar;

  const ClientConnection({super.key, required this.updateNavBar});

  @override
  State<ClientConnection> createState() => _ClientConnectionState();
}

class _ClientConnectionState extends State<ClientConnection> {
  late ScrollController _scrollController;
  // 记录上一次滚动位置,用于判断滚动方向
  double _lastScrollOffset = 0;

  @override
  void initState() {
    super.initState();
    _scrollController = ScrollController();
    // 绑定滚动监听
    _scrollController.addListener(_onScroll);
  }

  void _onScroll() {
    final currentOffset = _scrollController.offset;
    // 向下滚动(偏移量大于上次)且超过阈值时隐藏导航栏
    if (currentOffset > _lastScrollOffset && currentOffset > 10) {
      widget.updateNavBar(false);
    }
    // 向上滚动(偏移量小于上次)且超过阈值时显示导航栏
    else if (currentOffset < _lastScrollOffset - 10) {
      widget.updateNavBar(true);
    }
    // 更新上次滚动位置
    _lastScrollOffset = currentOffset;
  }

  @override
  void dispose() {
    // 销毁控制器,避免内存泄漏
    _scrollController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Sizer(builder: ((context, orientation, deviceType) {
      return Scaffold(
        appBar: AppBar(
          backgroundColor: Colors.white,
          elevation: 0,
          toolbarHeight: 10.h,
          title: Row(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              const Text(
                'Connections',
                style: TextStyle(color: Colors.black),
              ),
              SizedBox(width: 2.w),
              Container(
                width: 10.w,
                height: 6.h,
                decoration: BoxDecoration(
                  borderRadius: BorderRadius.circular(5),
                  color: Colors.blue,
                ),
              ),
            ],
          ),
        ),
        body: ListView.builder(
          controller: _scrollController,
          physics: const ClampingScrollPhysics(),
          itemBuilder: (_, i) => ListTile(title: Text('Item $i')),
          itemCount: 20,
        ),
      );
    }));
  }
}

关键说明

  1. 跨页面状态传递:通过回调函数将子页面的滚动状态传递给父页面,实现联动控制。
  2. 滚动方向判断:对比当前与上次滚动偏移量,添加阈值(10)避免微小滚动导致导航栏频繁切换。
  3. 资源管理:在子页面销毁时释放ScrollController,防止内存泄漏。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 19:15:38