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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.08 18:32:43