Why I can't use showModalBottomSheet inside floatingActionButton? It just keeps showing me this error:
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)
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;
});
},
),
],
),
),
),
);
}
}
Its because, the showModalBottomSheet tries to access the ancestor of type MaterialApp from the given context.
Use Builder widget to get new context with MaterialApp ancestor or Separate your MaterialAapp and Scaffold widgets into separate widgets.
Using 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));
});
}
),
),
I've got a solution. I don't know if it's the best but it works. The showModalBottomSheet should not have the same context as the materialapp, so it must be separated in a statelesswidget as you can see in this example.
import 'package:flutter/material.dart';
void main() => runApp(new MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Flutter App',
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
@override
Widget build(BuildContext context) {
return new MaterialApp(
home: new Scaffold(
appBar: new AppBar(title: const Text('Modal bottom sheet')),
body: new Center(
child: new RaisedButton(
child: const Text('SHOW BOTTOM SHEET'),
onPressed: () {
showModalBottomSheet<void>(context: context, builder: (BuildContext context) {
return new Container(
child: new Padding(
padding: const EdgeInsets.all(32.0),
child: new Text('This is the modal bottom sheet. Click anywhere to dismiss.',
textAlign: TextAlign.center,
style: new TextStyle(
color: Theme.of(context).accentColor,
fontSize: 24.0
)
)
)
);
});
}
)
)
)
);
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With