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

Flutter:如何实现Persistent_bottom_nav_bar_v2购物车数量自动更新

解决Persistent Bottom Navigation Bar购物车数量自动更新问题

问题背景

在Flutter应用中使用Persistent Bottom Navigation Bar Version 2包,购物车支持商品增减操作,但底部导航栏的购物车数量需要点击导航栏才会更新。期望调用购物车API获取数据后,底部导航栏的商品数量能自动刷新,无需手动点击。

核心问题分析

当前代码中,底部导航栏的_navbarItems()依赖cartManager.cartCount渲染,但没有监听cartCount的变化,只有点击导航栏时通过setState触发重建,因此无法自动响应购物车数据更新。

解决步骤

  1. 监听购物车状态变化:利用Bloc或状态管理类的监听机制,在购物车数据更新时触发UI重建。
  2. 开启导航栏状态管理:将PersistentTabView的stateManagement设为true,让导航栏能响应外部状态变化自动刷新。
  3. 同步最新购物车数据:确保导航栏渲染时能获取到最新的购物车数量。

修改后的完整代码

import 'dart:async';
import 'package:flutter_bloc/flutter_bloc.dart';
// 导入其他必要依赖包

class BottomNavBar extends StatefulWidget {
  bool? cameFromSplash;
  BottomNavBar({super.key, this.cameFromSplash = false});

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

class _BottomNavBarState extends State<BottomNavBar> {
  late CartBloc _cartBloc;
  CartManager cartManager = CartManager();

  PersistentTabController? _controller;

  @override
  void initState() {
    super.initState();
    _cartBloc = context.read<CartBloc>();
    _controller = PersistentTabController(initialIndex: 0);
    
    // 监听CartBloc状态变化,购物车数据更新时触发UI重建
    _cartBloc.stream.listen((state) {
      if (state is CartLoadedState) { // 根据你的Bloc实际状态类型调整
        setState(() {
          // 同步最新购物车数量到cartManager
          cartManager.cartCount = state.cartItems.length;
        });
      }
    });

    initConnectivity();
  }

  List<Widget> _buildScreens() {
    return [
      Screen1(),
      Screen2(),
      Screen3(),
      CartScreen(),
      Screen5(),
      Screen6(),
    ];
  }

  List<PersistentBottomNavBarItem> _navbarItems() {
    return [
      // 其他导航项保持不变
      PersistentBottomNavBarItem(
        icon: cartManager.cartCount == 0
            ? SvgPicture.asset(
                AppImages.pic1,
                height: 5.h,
                color: AppColors.kgrey,
              )
            : badges.Badge(
                badgeContent: Text(
                  cartManager.cartCount.toString(),
                  style: sans12light.copyWith(color: AppColors.kblack),
                ),
                child: SvgPicture.asset(
                  AppImages.pic1,
                  height: 5.h,
                  color: _controller!.index == 3
                      ? AppColors.kred
                      : AppColors.kgrey,
                ),
              ),
        activeColorPrimary: AppColors.kred,
        inactiveColorPrimary: Colors.grey,
      ),
      // 剩余导航项保持不变
    ];
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: AppColors.kwhite,
      body: PersistentTabView(
        context,
        screens: _buildScreens(),
        popAllScreensOnTapOfSelectedTab: true,
        popAllScreensOnTapAnyTabs: true,
        items: _navbarItems(),
        controller: _controller,
        stateManagement: true, // 开启导航栏状态管理
        navBarStyle: NavBarStyle.style8,
        onItemSelected: (index) {
          setState(() {
            _controller!.index = index;
          });
        },
      ),
    );
  }
}

// CustomNavBarWidget代码保持不变
class CustomNavBarWidget extends StatefulWidget {
  final int? selectedIndex;
  final List<PersistentBottomNavBarItem>? items;
  final ValueChanged<int>? onItemSelected;

  const CustomNavBarWidget({
    super.key,
    this.selectedIndex,
    required this.items,
    this.onItemSelected,
  });

  @override
  State<CustomNavBarWidget> createState() => _CustomNavBarWidgetState();
}

class _CustomNavBarWidgetState extends State<CustomNavBarWidget> {
  Widget _buildItem(PersistentBottomNavBarItem item, bool isSelected) {
    return Container(
      alignment: Alignment.center,
      height: kBottomNavigationBarHeight,
      child: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        crossAxisAlignment: CrossAxisAlignment.center,
        mainAxisSize: MainAxisSize.min,
        children: <Widget>[
          Flexible(
            child: IconTheme(
              data: IconThemeData(
                size: 26.0,
                color: isSelected
                    ? (item.activeColorSecondary ?? item.activeColorPrimary)
                    : item.inactiveColorPrimary ?? item.activeColorPrimary,
              ),
              child: isSelected ? item.icon : item.inactiveIcon ?? item.icon,
            ),
          ),
          Padding(
            padding: const EdgeInsets.only(top: 5.0),
            child: Material(
              type: MaterialType.transparency,
              child: FittedBox(
                child: Text(
                  item.title!,
                  style: TextStyle(
                    color: isSelected
                        ? (item.activeColorSecondary ?? item.activeColorPrimary)
                        : item.inactiveColorPrimary,
                    fontWeight: FontWeight.w400,
                    fontFamily: 'Calibri',
                    fontSize: 12.0,
                  ),
                ),
              ),
            ),
          ),
        ],
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    return Container(
      color: Colors.white,
      child: SizedBox(
        width: double.infinity,
        height: kBottomNavigationBarHeight,
        child: Row(
          mainAxisAlignment: MainAxisAlignment.spaceAround,
          children: widget.items!.map((item) {
            int index = widget.items!.indexOf(item);
            return Expanded(
              child: InkWell(
                onTap: () {
                  widget.onItemSelected!(index);
                },
                child: _buildItem(item, widget.selectedIndex == index),
              ),
            );
          }).toList(),
        ),
      ),
    );
  }
}

关键修改说明

  • Bloc状态监听:在initState中添加_cartBloc.stream.listen,当购物车数据加载完成时,调用setState同步最新数量并重建导航栏。
  • stateManagement配置:将PersistentTabView的stateManagement设为true,确保导航栏能感知外部状态变化并自动刷新。
  • 备选方案(ChangeNotifier):如果使用ChangeNotifier管理购物车状态,可替换为以下监听代码:
    @override
    void initState() {
      super.initState();
      cartManager.addListener(() {
        setState(() {});
      });
    }
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 20:00:58