Flutter Bloc侧边栏MenuItem点击onTap无法切换页面如何修复
问题修复方案
核心原因
你的代码存在两个核心问题导致页面无法切换:
NavigationBloc中冗余重写了旧版Bloc的initialStategetter,和构造函数传入的初始状态逻辑冲突SideBarLayout的初始页面写死不可配置,且点击事件获取Bloc实例时未关闭监听,可能出现上下文不匹配问题
分步修改代码
1. 修复 navigation_bloc.dart
删掉冗余的 initialState getter 重写代码,新版Bloc已经不需要通过重写这个属性设置初始状态,直接通过构造函数传参给父类即可:
import 'package:bloc/bloc.dart'; import '../pages/homepage.dart'; import '../pages/secondpage.dart'; import '../pages/thirdpage.dart'; enum NavigationEvents { HomePageClickedEvents, SecondPageClickedEvents, ThirdPageClickedEvents, } abstract class NavigationStates{} class NavigationBloc extends Bloc<NavigationEvents, NavigationStates>{ // 直接保留构造传参给父类即可,不需要重写initialState NavigationBloc(NavigationStates initialState) : super(initialState); @override Stream<NavigationStates> mapEventToState(NavigationEvents event) async*{ switch(event){ case NavigationEvents.HomePageClickedEvents: yield HomePage(); break; case NavigationEvents.SecondPageClickedEvents: yield SecondPage(); break; case NavigationEvents.ThirdPageClickedEvents: yield ThirdPage(); break; } } }
2. 修复 sidebar_layout.dart
给 SideBarLayout 增加可选的初始页面参数,支持自定义初始页面,不需要写死:
import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:solaris/pages/homepage.dart'; import '../bloc.navigation_bloc/navigation_bloc.dart'; import 'sidebar.dart'; class SideBarLayout extends StatelessWidget { // 增加可选参数,默认初始页为HomePage final NavigationStates initialState; const SideBarLayout({super.key, this.initialState = const HomePage()}); @override Widget build(BuildContext context) { return Scaffold( body: BlocProvider<NavigationBloc>( create: (context) => NavigationBloc(initialState), child: Stack( children: <Widget>[ BlocBuilder<NavigationBloc, NavigationStates>( builder: (context, navigationState) { return navigationState as Widget; }, ), const SideBar(), ], ), ), ); } }
3. 修复 MenuItem 点击事件
获取Bloc实例时添加 listen: false,避免回调中获取上下文出现异常:
MenuItem( icon: Icons.home, title: "HomePage", onTap: (){ print("test"); onIconPressed(); // 加listen: false,点击事件不需要监听Bloc状态变化 BlocProvider.of<NavigationBloc>(context, listen: false) .add(NavigationEvents.HomePageClickedEvents); } ),
验证逻辑
修改完成后,默认初始页为HomePage,如果需要指定其他初始页,使用时直接传参即可:
// 比如指定初始页为SecondPage const SideBarLayout(initialState: SecondPage())
点击侧边栏选项就能正常触发状态切换,BlocBuilder会自动响应状态变化更新页面。
内容的提问来源于stack exchange,提问作者Turf
相关产品推荐
相关产品推荐

