Flutter启动触发ArgumentError,请求代码排查与修复帮助
解决Flutter启动时的ArgumentError: Invalid argument(s)问题
我仔细排查了你的代码,这个错误的核心原因是**textNumber变量在初始化阶段未被赋值,始终为null**,当getText()方法尝试用null作为索引访问列表时,就会触发无效参数的报错。另外还有一个关键问题:你没有把用户选择的游戏类型传递给GamePage,导致切换不同列表的功能完全没有生效。
下面是具体的修复步骤和优化后的完整代码:
1. 修复StoryBrain的初始化逻辑
在StoryBrain的构造函数中,你生成了随机数但没有赋值给textNumber,而且需要根据传入的游戏类型初始化正确的随机索引:
// 修改构造函数,接收游戏类型参数并初始化textNumber StoryBrain({required bool gameTypeIsClasic}) { this.gameTypeIsClasic = gameTypeIsClasic; if (gameTypeIsClasic) { textNumber = random.nextInt(textListClasic.length); } else { textNumber = random.nextInt(textListTemel.length); } }
注意:
random.nextInt(n)会生成0到n-1的随机数,直接使用列表长度即可,不需要减1,避免出现索引越界的风险。
2. 传递用户选择的游戏类型到GamePage
修改FirstScreenMaterialApp中的按钮跳转逻辑,把用户选择的类型作为参数传递给GamePage:
// "Klasik"按钮的onPressed逻辑 onPressed: () { Navigator.push( context, MaterialPageRoute(builder: (context) => GamePage(isClassic: true)), ); }, // "Temel içgüdü(+18)"按钮的onPressed逻辑 onPressed: () { Navigator.push( context, MaterialPageRoute(builder: (context) => GamePage(isClassic: false)), ); },
然后修改GamePage,接收这个参数并传递给StoryBrain:
class GamePage extends StatefulWidget { final bool isClassic; // 添加接收参数 const GamePage({required this.isClassic, Key? key}) : super(key: key); _GamePageState createState() => _GamePageState(); } class _GamePageState extends State<GamePage> { late StoryBrain storyBrain; // 使用late延迟初始化 @override void initState() { super.initState(); // 用传递的参数初始化StoryBrain storyBrain = StoryBrain(gameTypeIsClasic: widget.isClassic); } // ... 其他代码保持不变 }
3. 优化StoryBrain的changeNumber方法
同样,这里的nextInt不需要减1,直接使用列表长度:
void changeNumber() { if (gameTypeIsClasic) { textNumber = random.nextInt(textListClasic.length); } else { textNumber = random.nextInt(textListTemel.length); } }
修改后的完整代码
main.dart
import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'story_brain.dart'; void main() => runApp(MyApp()); class MyApp extends StatelessWidget { Widget build(BuildContext context) { return MaterialApp( theme: ThemeData.dark(), home: FirstScreenMaterialApp(), // 直接启动初始选择页面 ); } } class FirstScreenMaterialApp extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( backgroundColor: Colors.purple[900], body: Container( child: Padding( padding: const EdgeInsets.fromLTRB(20, 10, 20, 50), child: Column( mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.center, children: <Widget>[ Image( image: AssetImage("assets/images/logo.png"), width: 300, // 修复无效的width值 height: 400, ), Expanded( child: FlatButton( onPressed: () { Navigator.push( context, MaterialPageRoute(builder: (context) => GamePage(isClassic: true)), ); }, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(15)), color: Colors.lightBlue, child: Center( child: Text( "Klasik", style: TextStyle(fontSize: 40), ), ), ), ), SizedBox(height: 20), Expanded( child: FlatButton( onPressed: () { Navigator.push( context, MaterialPageRoute(builder: (context) => GamePage(isClassic: false)), ); }, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(15)), color: Colors.red, child: Center( child: Text( "Temel içgüdü(+18)", style: TextStyle(fontSize: 40), ), ), ), ), ], ), ), ), ); } } class GamePage extends StatefulWidget { final bool isClassic; const GamePage({required this.isClassic, Key? key}) : super(key: key); _GamePageState createState() => _GamePageState(); } class _GamePageState extends State<GamePage> { late StoryBrain storyBrain; @override void initState() { super.initState(); storyBrain = StoryBrain(gameTypeIsClasic: widget.isClassic); } Widget build(BuildContext context) { return Scaffold( // 移除多余的外层Center组件 body: Container( color: Colors.purple[800], padding: EdgeInsets.symmetric(vertical: 50.0, horizontal: 30.0), child: Column( crossAxisAlignment: CrossAxisAlignment.stretch, mainAxisAlignment: MainAxisAlignment.end, children: <Widget>[ Expanded( flex: 20, child: Row( mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[ Expanded( flex: 0, child: Icon( Icons.whatshot, size: 70, color: storyBrain.changeHeatBarColor(), ), ), Expanded( flex: 1, child: Text( storyBrain.updateHeat(), style: TextStyle( fontSize: 50, fontFamily: "CustomFamilyName", color: storyBrain.changeHeatBarColor(), ), ), ) ], ), ), Expanded( flex: 100, child: Center( child: Container( padding: EdgeInsets.all(20), margin: EdgeInsets.fromLTRB(20, 0, 20, 60), width: 300, height: 250, decoration: BoxDecoration( borderRadius: BorderRadius.circular(20), color: storyBrain.setColor(), ), child: Text( storyBrain.getText(), style: TextStyle(fontSize: 30.0), ), ), ), ), Expanded( flex: 10, child: FlatButton( onPressed: () { setState(() { storyBrain.changeNumber(); // setState触发重绘,自动获取最新数据 }); }, color: storyBrain.setColor(), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(15), ), child: Center( child: Text( "Değiştir", style: TextStyle( color: Colors.white, fontSize: 30.0, ), ), ), ), ), SizedBox(height: 20) ], ), ), ); } }
story_brain.dart
import 'package:flutter/material.dart'; import 'story.dart'; import 'dart:math'; class StoryBrain { static Random random = Random(); int textNumber = 0; // 初始化默认值,避免null风险 bool gameTypeIsClasic = false; static List<Story> textListClasic = [ Story("text content 2", "göm"), Story("text content 1", "öv"), Story("text content 3", "göm"), Story("text content 4", "öv") ]; static List<Story> textListTemel = [ Story("text content 1", "göm"), Story("text content 2", "öv"), Story("text content 3", "göm"), Story("text content 4", "öv") ]; int heat = 1; StoryBrain({required bool gameTypeIsClasic}) { this.gameTypeIsClasic = gameTypeIsClasic; if (gameTypeIsClasic) { textNumber = random.nextInt(textListClasic.length); } else { textNumber = random.nextInt(textListTemel.length); } } void changeNumber() { if (gameTypeIsClasic) { textNumber = random.nextInt(textListClasic.length); } else { textNumber = random.nextInt(textListTemel.length); } } String getText() { return gameTypeIsClasic ? textListClasic[textNumber].textContent : textListTemel[textNumber].textContent; } String getTextType() { return gameTypeIsClasic ? textListClasic[textNumber].textType : textListTemel[textNumber].textType; } Color setColor() { return getTextType() == "öv" ? Colors.blue : Colors.red; } String updateHeat() { if (getTextType() == "öv") { if (heat > 1 && heat < 20) heat -= 1; else if (heat >= 20 && heat < 100) heat -= 10; else if (heat >= 100 && heat < 500) heat -= 25; else if (heat >= 500) heat = heat ~/ 3; } else { if (heat < 1000) heat *= 2; else heat += 100; } return "$heat x"; } Color changeHeatBarColor() { if (heat >= 50 && heat < 100) return Colors.orange; else if (heat >= 100 && heat < 500) return Colors.redAccent; else if (heat >= 500) return Colors.red[800]!; else return Colors.blue; } }
额外优化说明
- 移除了多余的
FirstScreen类,直接将FirstScreenMaterialApp作为应用初始页面 - 简化了
setState内的逻辑,只需要修改storyBrain的状态,重绘时会自动获取最新数据 - 修复了
Image组件中无效的width值 - 给
textNumber设置了初始默认值,进一步避免null引用问题
这样修改后,启动应用就不会再出现ArgumentError,而且用户选择不同游戏类型时,会正确切换对应的内容列表。
内容的提问来源于stack exchange,提问作者glorry
相关产品推荐
相关产品推荐

