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

Flutter导航报错:跳转至V页面时触发空检查运算符使用错误

问题分析与修复

错误原因

  1. 点击"Next"按钮时先执行Navigator.pop(context)关闭第一个底部弹窗,此时传入aboutnoteorfolder的context已失效,调用Navigator.of(context)会返回null,触发空检查错误。
  2. AnimationController的vsync参数传入Navigator.of(context)是错误用法——NavigatorState并不实现TickerProvider接口,无法作为动画的同步提供者。

修复方案

  1. 将MyHomePage改为StatefulWidget,混入SingleTickerProviderStateMixin以提供合法的TickerProvider。
  2. 调整aboutnoteorfolder函数,新增TickerProvider参数用于初始化AnimationController。
  3. 调用aboutnoteorfolder时,使用页面自身的context而非弹窗的失效context,并传入当前State作为vsync。
  4. 确保导航逻辑中使用有效的context。

修复后的完整代码

import 'package:flutter/material.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSwatch(primarySwatch: Colors.deepPurple),
        useMaterial3: true,
      ),
      home: const MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

// 改为StatefulWidget并混入SingleTickerProviderStateMixin
class MyHomePage extends StatefulWidget {
  const MyHomePage({Key? key, required this.title}) : super(key: key);

  final String title;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> with SingleTickerProviderStateMixin {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Theme.of(context).colorScheme!.primary,
        title: Text(widget.title),
      ),
      body: const Center(
        child: Text('You have pushed the button this many times:'),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          _showModalBottomSheet(context);
        },
        tooltip: 'Increment',
        child: const Icon(Icons.add),
      ),
    );
  }
}

void _showModalBottomSheet(BuildContext context) {
  showModalBottomSheet(
    context: context,
    builder: (BuildContext sheetContext) {
      return Container(
        height: 200,
        color: Colors.white,
        child: Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            mainAxisSize: MainAxisSize.min,
            children: <Widget>[
              const Text(
                'Modal Bottom Sheet',
                style: TextStyle(
                  fontSize: 20,
                  fontWeight: FontWeight.bold,
                ),
              ),
              const SizedBox(height: 20),
              ElevatedButton(
                onPressed: () {
                  Navigator.pop(sheetContext);
                  // 获取页面的State,用于提供vsync
                  final pageState = context.findAncestorStateOfType<_MyHomePageState>()!;
                  aboutnoteorfolder(
                    context, // 使用页面的context而非弹窗的context
                    vsync: pageState,
                    arrowoperation: () {
                      Navigator.push(context, MaterialPageRoute(
                        builder: (context) {
                          return const V();
                        },
                      ));
                    },
                  );
                },
                child: const Text('Next'),
              ),
            ],
          ),
        ),
      );
    },
  );
}

// 新增vsync参数,接收TickerProvider
void aboutnoteorfolder(
  BuildContext context, {
  required TickerProvider vsync,
  required Function() arrowoperation,
}) {
  final AnimationController controller = AnimationController(
    vsync: vsync, // 使用传入的TickerProvider
    reverseDuration: const Duration(milliseconds: 250),
    duration: const Duration(milliseconds: 700),
  );
  showModalBottomSheet(
      elevation: 0,
      transitionAnimationController: controller,
      useSafeArea: true,
      isScrollControlled: true,
      backgroundColor: Colors.transparent,
      barrierColor: const Color.fromARGB(90, 0, 0, 0),
      context: context,
      builder: (context) {
        return Padding(
            padding: EdgeInsets.only(
                bottom: MediaQuery.of(context).size.width * 0.02),
            child: GestureDetector(
              onTap: arrowoperation,
              child: Container(
                width: MediaQuery.of(context).size.width * .955,
                height: MediaQuery.of(context).size.width * .65,
                decoration: BoxDecoration(
                  color: const Color.fromARGB(255, 0, 128, 255),
                  border: Border.all(
                    width: MediaQuery.of(context).size.width * 0.0030,
                    color: const Color.fromARGB(120, 255, 255, 255),
                  ),
                  borderRadius: BorderRadius.all(Radius.circular(
                    MediaQuery.of(context).size.width * 0.11,
                  )),
                ),
                child: const Center(
                  child: Text("Navigate"),
                ),
              ),
            ));
      });
}

class V extends StatelessWidget {
  const V({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return const Scaffold(
      body: Center(child: Text("V Page")),
    );
  }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 21:58:14