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

Flutter带BottomNavigationBar页面无法在模拟器运行:类型不匹配错误问题

解决Flutter路由中_MainPage无法赋值给Widget的问题

嘿,这个问题其实是个常见的新手小坑——你搞混了StatefulWidget本身和它对应的State子类啦!

错误原因分析

你定义的_MainPage是MyApp这个StatefulWidget对应的State子类,它的类型是State<MyApp>,并不是Widget类型。而Flutter路由的builder函数要求返回一个Widget对象,所以直接在路由里写_MainPage()就会触发类型不匹配的错误:

Error: A value of type '_MainPage' can't be assigned to a variable of type 'Widget'

快速修复方案

你只需要把路由配置里的_MainPage()换成MyApp()就可以了,因为MyApp才是真正的StatefulWidget(属于Widget类型):

routes: {
  '/LogIn': (BuildContext context) => LogInPage(),
  '/QRScan': (BuildContext context) => QRCodePage(),
  '/LogIn/Registr': (BuildContext context) => RegistrPage(),
  '/Main': (BuildContext context) => MyApp(), // 这里改成MyApp()
},

更规范的代码优化(推荐)

不过从命名规范来说,MyApp这个名字不太合适,因为它其实是你的主页面,不是整个App的根组件。建议你调整命名,让代码更清晰:

  1. 把MyApp改名为MainPage(作为主页面的StatefulWidget)
  2. 把_MainPage改名为_MainPageState(符合Flutter State类的命名习惯:Widget名+State)

调整后的完整代码如下:

import 'package:flutter/material.dart';

class LogInPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text("Log In")),
      body: Center(
        child: Row(
          mainAxisAlignment: MainAxisAlignment.center, // 让按钮居中显示
          children: <Widget>[
            RaisedButton(
              onPressed: () {
                Navigator.pushNamed(context, '/Main');
              },
              child: Text("Log In")),
            SizedBox(width: 16), // 按钮之间增加间距
            RaisedButton(
              onPressed: () {
                Navigator.pushNamed(context, '/LogIn/Registr');
              },
              child: Text("Registration")),
          ],
        )),
    );
  }
}

class QRCodePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text("QR Scan")),
      body: Center(
        child: RaisedButton(
          onPressed: () {
            Navigator.pushNamed(context, '/Main');
          },
          child: Text("Scan")),
      ));
  }
}

class RegistrPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text("Registration")),
      body: Center(
        child: RaisedButton(
          onPressed: () {
            Navigator.pushNamed(context, '/Main');
          },
          child: Text("Log In")),
      ));
  }
}

// 调整命名,符合Flutter代码规范
class MainPage extends StatefulWidget {
  @override
  _MainPageState createState() => _MainPageState();
}

class _MainPageState extends State<MainPage> {
  int _currentIndex = 0;
  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: AppBar(title: Text("Main")),
      body: Container(),
      bottomNavigationBar: BottomNavigationBar(
        items: [
          BottomNavigationBarItem(
              icon: Icon(Icons.home), backgroundColor: Colors.blue),
          BottomNavigationBarItem(
              icon: Icon(Icons.qr_code), backgroundColor: Colors.blue),
          BottomNavigationBarItem(
              icon: Icon(Icons.restaurant_menu), backgroundColor: Colors.blue),
          BottomNavigationBarItem(
              icon: Icon(Icons.shopping_basket), backgroundColor: Colors.blue),
        ],
        onTap: (index){
          setState(() {
            _currentIndex = index;
          });
        },
      ),
    );
  }
}

void main() {
  runApp(MaterialApp(
    initialRoute: '/LogIn',
    routes: {
      '/LogIn': (BuildContext context) => LogInPage(),
      '/QRScan': (BuildContext context) => QRCodePage(),
      '/LogIn/Registr': (BuildContext context) => RegistrPage(),
      '/Main': (BuildContext context) => MainPage(), // 使用调整后的MainPage
    },
  ));
}

另外我还顺手加了两个小优化:给LogInPage的Row加了mainAxisAlignment: MainAxisAlignment.center让按钮居中,加了SizedBox(width: 16)让两个按钮之间有间距,视觉体验更好~

内容的提问来源于stack exchange,提问作者Максим Мазепа

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.29 06:22:33