手势捕获的颤振异常。在 showModalBottomSheet 中找不到 MediaQuery 小部件

pho*_*ong 4 android dart flutter

为什么我不能在 floatActionButton 中使用 showModalBottomSheet?它只是不断向我显示此错误:

I/flutter (16368): ??? EXCEPTION CAUGHT BY GESTURE ????????????????????????????????????????????????????????????????????
I/flutter (16368): The following assertion was thrown while handling a gesture:
I/flutter (16368): No MediaQuery widget found.
I/flutter (16368): MyApp widgets require a MediaQuery widget ancestor.
I/flutter (16368): The specific widget that could not find a MediaQuery ancestor was:
I/flutter (16368):   MyApp
I/flutter (16368): The ownership chain for the affected widget is: "MyApp ? [root]"
I/flutter (16368): Typically, the MediaQuery widget is introduced by the MaterialApp or WidgetsApp widget at the top of
I/flutter (16368): your application widget tree.
I/flutter (16368): 
I/flutter (16368): When the exception was thrown, this was the stack:
I/flutter (16368): #0      debugCheckHasMediaQuery.<anonymous closure> (package:flutter/src/widgets/debug.dart:211:7)
I/flutter (16368): #1      debugCheckHasMediaQuery (package:flutter/src/widgets/debug.dart:223:4)
I/flutter (16368): #2      showModalBottomSheet (package:flutter/src/material/bottom_sheet.dart:469:10)
I/flutter (16368): #3      _MyAppState.build.<anonymous closure> (package:flutter_happy_habits/main.dart:32:29)
I/flutter (16368): #4      _InkResponseState._handleTap (package:flutter/src/material/ink_well.dart:706:14)
Run Code Online (Sandbox Code Playgroud)
import 'package:flutter/material.dart';
import './models/home.dart';
import 'models/progress.dart';

void main() => runApp(MyApp());

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  int _selectedPage = 0;
  final _pageOptions = [
    Home(),
    Progress(),
    Progress(),
  ];

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      debugShowCheckedModeBanner: true,
      home: new Scaffold(
        appBar: AppBar(title: Text('Flutter Demo')),
        body: _pageOptions[_selectedPage],
        floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,
        floatingActionButton: FloatingActionButton(
          child: Icon(Icons.add),
          onPressed: () { showModalBottomSheet(
            context: context,
            builder: (context) {
              return Text('Modal bottom sheet', style: TextStyle(fontSize: 30));
            });
          }
        ),
        bottomNavigationBar: BottomAppBar(
          shape: CircularNotchedRectangle(),
          notchMargin: 4.0,
          child: new Row(
            mainAxisSize: MainAxisSize.max,
            mainAxisAlignment: MainAxisAlignment.spaceAround,
            children: <Widget>[
              IconButton(
                icon: Icon(Icons.home),
                onPressed: () {
                  print("Home");
                  setState(() {
                    _selectedPage = 0;
                  });
                },
              ),
              IconButton(
                icon: Icon(Icons.insert_chart),
                onPressed: () {
                  print("Progress");
                  setState(() {
                    _selectedPage = 1;
                  });
                },
              ),
            ],
          ),
        ),
      ),
    );
  }
}
Run Code Online (Sandbox Code Playgroud)

Cra*_*Cat 30

这是因为,showModalBottomSheet尝试MaterialApp从给定的context.

使用Builder小部件获得新contextMaterialApp祖先或将您的小部件MaterialAappScaffold小部件分成单独的小部件。

使用Builder

floatingActionButton: Builder(
  builder: (context) => FloatingActionButton(
      child: Icon(Icons.add),
      onPressed: () { showModalBottomSheet(
          context: context,
          builder: (context) {
            return Text('Modal bottom sheet', style: TextStyle(fontSize: 30));
          });
      }
  ),
),
Run Code Online (Sandbox Code Playgroud)

  • 但为什么?为什么我们需要“Builder”?我读了一些教程,但没有人提到这一点。像这里一样:[底部表教程](https://medium.com/flutterpub/flutter-5-bottom-sheet-2d56bf9f3bc) (3认同)
  • @Gabriel,当您调用“showModalBottomSheet()”时,您将传递一个“context”对象。此上下文用于查找祖先“MaterialApp”。 (3认同)
  • @Gabriel在查询中,您可以看到他传递了从“build(BuildContext context)”获取的“context”。它不包含任何“MaterialApp”祖先。 (3认同)
  • @Gabriel但是在构建方法内部使用了一个“MaterialApp”小部件。因此,我们可以使用“Builder”小部件获取新的“上下文”,然后将该上下文传递给“showModalBottomSheet” (3认同)
  • @Gabriel [底表教程](https://medium.com/flutterpub/flutter-5-bottom-sheet-2d56bf9f3bc) 这里的 `MaterialApp` 小部件没有放置在 `MyHomePage` 小部件中,而是放置在单独的无状态小部件中。这里“MyHomePage”的作用类似于“Builder”小部件,并通过“build”方法提供新的“context”。 (3认同)