如何在Flutter中从其他Dart脚本获取变量更新值到main.dart
问题核心原因
- 你虽然将
screenIndex设为静态变量可以跨实例访问,但BottomNavigationBarTravel里修改这个值后,没有通知上层的MyHomePage刷新状态,所以就算你调用getIndex拿到了新值,页面也不会自动切换 - 你当前的
main.dart里没有将BottomNavigationBarTravel组件放到widget树中,底部导航栏根本不会显示,点击交互也不会触发
修改方案
第一步:调整bottom_navigation_bar.dart的逻辑
不需要额外在组件内实例化自身,直接操作静态变量即可,同时新增回调函数把索引变化通知给上层:
import 'package:flutter/material.dart'; import 'package:flutter_svg/flutter_svg.dart'; import 'package:google_fonts/Google_fonts.dart'; class BottomNavigationBarTravel extends StatefulWidget { // 定义索引变化回调 final Function(int) onIndexChanged; static int screenIndex = 0; int get getIndex => screenIndex; set setIndex(int index) => screenIndex = index; // 构造函数接收回调参数 const BottomNavigationBarTravel({super.key, required this.onIndexChanged}); @override _BottomNavigationBarTravelState createState() => _BottomNavigationBarTravelState(); } class _BottomNavigationBarTravelState extends State<BottomNavigationBarTravel> { int _selectedIndex = 0; void _onItemTapped(int index) { setState(() { _selectedIndex = index; widget.setIndex = _selectedIndex; // 触发回调通知上层索引更新 widget.onIndexChanged(_selectedIndex); }); } var bottomNavStyle = GoogleFonts.lato(fontSize: 12, fontWeight: FontWeight.w500); @override Widget build(BuildContext context) { return Container( height: 86.4, decoration: BoxDecoration(color: Colors.white, boxShadow: [ BoxShadow( color: Colors.grey.withOpacity(0.3), spreadRadius: 2, blurRadius: 15, offset: Offset(0, 5)) ]), child: BottomNavigationBar( items: <BottomNavigationBarItem>[ BottomNavigationBarItem( icon: _selectedIndex == 0 ? SvgPicture.asset('assets/svg/icon_home_colored.svg') : SvgPicture.asset('assets/svg/icon_home.svg'), label: 'Home', ), BottomNavigationBarItem( icon: _selectedIndex == 1 ? SvgPicture.asset('assets/svg/icon_heart_colored.svg') : SvgPicture.asset('assets/svg/icon_heart.svg'), label: 'Heart', ), BottomNavigationBarItem( icon: _selectedIndex == 2 ? SvgPicture.asset('assets/svg/icon_plus_colored.svg') : SvgPicture.asset('assets/svg/icon_plus.svg'), label: 'Plus', ), BottomNavigationBarItem( icon: _selectedIndex == 3 ? SvgPicture.asset( 'assets/svg/icon_search_colored.svg') : SvgPicture.asset('assets/svg/icon_search.svg'), label: 'Search', ), BottomNavigationBarItem( icon: _selectedIndex == 4 ? SvgPicture.asset('assets/svg/icon_user_colored.svg') : SvgPicture.asset('assets/svg/icon_user.svg'), label: 'User', ) ], currentIndex: _selectedIndex, onTap: _onItemTapped, backgroundColor: Colors.transparent, type: BottomNavigationBarType.fixed, selectedFontSize: 12, showSelectedLabels: false, showUnselectedLabels: false, elevation: 0, ), ); } }
第二步:修改main.dart的结构,加入底部导航、监听索引变化刷新页面
import 'package:flutter/material.dart'; import 'package:fluttertravelapp/screens/category_screen.dart'; import 'package:fluttertravelapp/screens/favorites_screen.dart'; import 'package:fluttertravelapp/screens/home_screen.dart'; import 'package:fluttertravelapp/screens/search_screen.dart'; import 'package:fluttertravelapp/widgets/bottom_navigation_bar.dart'; void main() { runApp(const MyApp()); } class MyApp extends StatelessWidget { const MyApp({super.key}); @override Widget build(BuildContext context) { return MaterialApp( debugShowCheckedModeBanner: false, home: MyHomePage(), ); } } final List<Widget> _children = [ HomeScreen(), FavoritesScreen(), CategoryScreen(), SearchScreen(), // 补全第5个用户页占位,替换为你自己的用户页面即可 Scaffold(body: Center(child: Text('用户页面'))), ]; class MyHomePage extends StatefulWidget { @override State<MyHomePage> createState() => _MyHomePageState(); } class _MyHomePageState extends State<MyHomePage> { int _currentIndex = BottomNavigationBarTravel.screenIndex; @override Widget build(BuildContext context) { return Scaffold( body: _children[_currentIndex], // 把自定义底部导航加入页面 bottomNavigationBar: BottomNavigationBarTravel( onIndexChanged: (index) { // 收到索引更新后触发重绘切换页面 setState(() { _currentIndex = index; }); }, ), ); } }
扩展说明
如果后续项目中跨组件共享状态的场景增多,可以考虑使用Provider、Riverpod、Bloc这类状态管理框架,无需手动传递回调就可以实现全局状态的访问和监听。
内容的提问来源于stack exchange,提问作者NabsDev
相关产品推荐
相关产品推荐

