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

Dart代码中尝试次数不足时切换页面报错:需传入BuildContext参数

解决Dart类中Navigator跳转缺少BuildContext的问题

问题根源

你的Spiel_nummer是普通业务逻辑类,本身不持有Flutter的BuildContext,而Navigator必须依赖上下文才能完成页面跳转,所以直接在类里调用Navigator.push会报错。

解决方案

方案一:直接传递BuildContext参数

修改gameover方法,让它接收BuildContext,同时在调用guessnumber时传入上下文:

  1. 修改Spiel_nummer类的方法:
class Spiel_nummer {
  Random random = new Random();
  int trys = 5;
  int random_number = 0;
  int lastguess = 0;
  dynamic ico = null;
  int score = 0;
  int generate_random_number() => random.nextInt(101);

  bool guessnumber(int number, BuildContext context) {
    print(number);
    if (number == random_number) {
      reset();
      score++;
      return true;
    } else {
      trys--;
      if (number < random_number) {
        lastguess = 0;
        ico = Icons.arrow_upward;
      } else if (number > random_number) {
        lastguess = 1;
        ico = Icons.arrow_downward;
      }
      if (trys <= 0) {         
        gameover(context);
        score = 0;
        reset();
      }
      return false;
    }
  }

  void gameover(BuildContext context){
    Navigator.push(context, MaterialPageRoute(builder: (context) => MyApp()));
  } 

  void reset() {
    trys = 5;
    random_number = generate_random_number();
  }
}
  1. 在UI层调用时传入上下文:
// 假设在State类的按钮点击事件中
ElevatedButton(
  onPressed: () {
    int inputNumber = int.parse(_inputController.text);
    spiel.guessnumber(inputNumber, context);
  },
  child: const Text("猜数字"),
)

方案二:用回调函数解耦(推荐)

让业务类和UI层解耦,通过回调通知UI层处理页面跳转,避免业务类依赖BuildContext:

  1. 修改Spiel_nummer类,添加游戏结束回调:
import 'package:flutter/material.dart';

class Spiel_nummer {
  Random random = new Random();
  int trys = 5;
  int random_number = 0;
  int lastguess = 0;
  dynamic ico = null;
  int score = 0;
  // 定义游戏结束回调
  VoidCallback? onGameOver;

  int generate_random_number() => random.nextInt(101);

  bool guessnumber(int number) {
    print(number);
    if (number == random_number) {
      reset();
      score++;
      return true;
    } else {
      trys--;
      if (number < random_number) {
        lastguess = 0;
        ico = Icons.arrow_upward;
      } else if (number > random_number) {
        lastguess = 1;
        ico = Icons.arrow_downward;
      }
      if (trys <= 0) {         
        onGameOver?.call();
        score = 0;
        reset();
      }
      return false;
    }
  }

  void reset() {
    trys = 5;
    random_number = generate_random_number();
  }
}
  1. 在UI层初始化时绑定回调:
class GamePage extends StatefulWidget {
  const GamePage({super.key});

  @override
  State<GamePage> createState() => _GamePageState();
}

class _GamePageState extends State<GamePage> {
  final Spiel_nummer spiel = Spiel_nummer();
  final _inputController = TextEditingController();

  @override
  void initState() {
    super.initState();
    // 绑定游戏结束回调
    spiel.onGameOver = () {
      Navigator.push(context, MaterialPageRoute(builder: (context) => const MyApp()));
    };
    // 初始化随机数
    spiel.random_number = spiel.generate_random_number();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            TextField(
              controller: _inputController,
              keyboardType: TextInputType.number,
              decoration: const InputDecoration(hintText: "输入数字"),
            ),
            const SizedBox(height: 20),
            ElevatedButton(
              onPressed: () {
                int inputNumber = int.parse(_inputController.text);
                spiel.guessnumber(inputNumber);
              },
              child: const Text("猜数字"),
            ),
          ],
        ),
      ),
    );
  }
}

说明

方案二更符合单一职责原则,业务类只负责处理游戏逻辑,页面跳转交给UI层处理,代码更易维护和测试。如果是简单场景,方案一也能快速解决问题。

内容的提问来源于stack exchange,提问作者Xandertime2222

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 03:05:23