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

Flutter底部导航栏切换异常:点击按钮无法跳转至Nilai页面

Flutter项目问题修复:未定义变量与页面切换失效

问题原因分析

  1. 「Undefined name '_selectedIndex'」错误:_selectedIndex是_HomePageState类的私有变量,HomeScreen作为独立的无状态组件无法直接访问该变量;同时setState是State类的方法,无状态组件中不能调用。
  2. 页面切换无反应:按钮的点击逻辑无法修改父组件_HomePageState中的_selectedIndex值,导致底部导航栏状态和页面内容都无法更新。

修复方案

通过回调函数让子组件HomeScreen通知父组件更新状态:

  • 给HomeScreen添加回调参数,传递切换页面的请求
  • 在父组件_HomePageState中实现回调逻辑,调用setState更新_selectedIndex
  • 移除HomeScreen中错误的setState和_selectedIndex引用

修改后的完整代码

import 'package:flutter/material.dart';
import 'package:carousel_slider/carousel_slider.dart';
import 'nilai.dart';
import 'evaluasi.dart';
import 'profil.dart';

class HomePage extends StatefulWidget {
  @override
  _HomePageState createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  int _selectedIndex = 0;

  static List<Widget> _widgetOptions = <Widget>[
    // 传递回调函数给HomeScreen
    HomeScreen(onNavigateToNilai: () {
      setState(() {
        _selectedIndex = 1;
      });
    }),
    NilaiScreen(),
    EvaluasiBelajarScreen(),
    ProfilScreen(),
  ];

  void _onItemTapped(int index) {
    setState(() {
      _selectedIndex = index;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: IndexedStack(
        index: _selectedIndex,
        children: _widgetOptions,
      ),
      bottomNavigationBar: BottomNavigationBar(
        items: const <BottomNavigationBarItem>[
          BottomNavigationBarItem(
            icon: Icon(Icons.home),
            label: 'Home',
          ),
          BottomNavigationBarItem(
            icon: Icon(Icons.rocket_launch),
            label: 'Nilai',
          ),
          BottomNavigationBarItem(
            icon: Icon(Icons.assignment),
            label: 'Evaluasi',
          ),
          BottomNavigationBarItem(
            icon: Icon(Icons.person),
            label: 'Profil',
          ),
        ],
        currentIndex: _selectedIndex,
        selectedItemColor: Colors.blue,
        unselectedItemColor: Colors.grey,
        backgroundColor: Colors.white,
        onTap: _onItemTapped,
      ),
    );
  }
}

class HomeScreen extends StatelessWidget {
  // 定义回调函数
  final VoidCallback onNavigateToNilai;

  const HomeScreen({super.key, required this.onNavigateToNilai});

  final List<String> imageList = [
    'assets/images/gambar1.jpg',
    'assets/images/gambar2.jpg',
    'assets/images/gambar3.jpg',
  ];

  final List<String> subjects = [
    'Matematika',
    'Bahasa Inggris',
    'IPA',
    'IPS',
    'Olahraga',
    'Seni Budaya',
    'PPKn',
    'Agama',
  ];

  @override
  Widget build(BuildContext context) {
    return SingleChildScrollView(
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          Padding(
            padding: EdgeInsets.only(
              top: 60.0,
              left: 24.0,
            ),
            child: Text(
              'Selamat Datang',
              style: TextStyle(
                color: Colors.black,
                fontWeight: FontWeight.w300,
                fontSize: 18.0,
              ),
            ),
          ),
          Padding(
            padding: EdgeInsets.only(left: 24.0),
            child: Text(
              'Bagus Lindu!',
              style: TextStyle(
                color: Colors.black,
                fontWeight: FontWeight.bold,
                fontSize: 18.0,
              ),
              overflow: TextOverflow.visible,
            ),
          ),
          SizedBox(height: 20.0),
          CarouselSlider(
            options: CarouselOptions(
              height: 200.0,
              autoPlay: true,
              enlargeCenterPage: true,
              enableInfiniteScroll: true,
            ),
            items: imageList.map((item) {
              return Builder(
                builder: (BuildContext context) {
                  return Container(
                    width: MediaQuery.of(context).size.width,
                    margin: EdgeInsets.symmetric(horizontal: 6.0),
                    child: ClipRRect(
                      borderRadius: BorderRadius.circular(8.0),
                      child: Image.asset(
                        item,
                        fit: BoxFit.cover,
                      ),
                    ),
                  );
                },
              );
            }).toList(),
          ),
          SizedBox(height: 24.0),
          Padding(
            padding: EdgeInsets.only(left: 30.0),
            child: Text(
              'Pilih Mata Pelajaran:',
              style: TextStyle(
                fontWeight: FontWeight.bold,
                fontSize: 16.0,
              ),
            ),
          ),
          ListView.builder(
            shrinkWrap: true,
            physics: NeverScrollableScrollPhysics(),
            itemCount: subjects.length,
            itemBuilder: (context, index) {
              return Container(
                margin: EdgeInsets.only(
                    left: 24.0, right: 24.0, top: 2.0, bottom: 5.0),
                child: Card(
                  elevation: 0.5,
                  shape: RoundedRectangleBorder(
                    borderRadius: BorderRadius.circular(8.0),
                  ),
                  child: ListTile(
                    contentPadding:
                        EdgeInsets.symmetric(vertical: 8.0, horizontal: 16.0),
                    title: Text(subjects[index]),
                    trailing: ElevatedButton(
                      onPressed: onNavigateToNilai, // 调用回调函数
                      child: Text('Lihat Detail Nilai'),
                    ),
                  ),
                ),
              );
            },
          ),
        ],
      ),
    );
  }
}

修复说明

  • 在HomeScreen中新增onNavigateToNilai回调参数,用于触发父组件的状态更新
  • 父组件_HomePageState在初始化HomeScreen时,传入回调函数实现_selectedIndex的更新
  • 按钮点击逻辑直接调用回调函数,避免了直接访问父组件私有变量和调用setState的错误

内容的提问来源于stack exchange,提问作者Bagus Lindu Pamungkas

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 00:27:01