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

如何在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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 07:36:01