[英]Unhandled Exception: No MediaQuery widget found - flutter ShowModalButtonSheet
I'm working on this project to show a showModalBottomSheet widget after pressing on markers (current location) of Google Maps, using onTap() method of Marker.我正在使用 Marker 的 onTap() 方法在按下 Google 地图的标记(当前位置)后显示一个showModalBottomSheet小部件。 But it's showing Exception: MyApp widgets require a MediaQuery widget ancestor.
但它显示异常: MyApp 小部件需要 MediaQuery 小部件祖先。
import 'package:flutter/material.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';
import 'package:geolocator/geolocator.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
GoogleMapController mapController;
Position currentLocation;
LatLng _center;
Set<Marker> _markers = Set();
@override
void initState() {
// TODO: implement initState
super.initState();
setLocation();
}
void _onMapCreated(GoogleMapController controller) {
mapController = controller;
}
void setLocation() async {
currentLocation = await Geolocator()
.getCurrentPosition(desiredAccuracy: LocationAccuracy.high);
setState(() {
_center = LatLng(currentLocation.latitude, currentLocation.longitude);
});
}
Widget googleMap() {
addMarkers();
return GoogleMap(
onMapCreated: _onMapCreated,
myLocationEnabled: true,
initialCameraPosition: CameraPosition(
target: _center,
),
markers: _markers,
);
}
void addMarkers() {
_markers.addAll([
Marker(
markerId: MarkerId('current location'),
position: _center,
onTap: () {
print("tapped !!!!!!");
showModalBottomSheet(
context: context,
builder: (context) {
return Text('Modal bottom sheet', style: TextStyle(fontSize: 30));
});
},
),
]);
}
@override
Widget build(BuildContext context) {
print("Debug: build called!!!");
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('Google Map'),
backgroundColor: Colors.blue,
),
body: (_center == null)
? Center(child: CircularProgressIndicator())
: googleMap(),
),
);
}
}
How can I solve this?我该如何解决这个问题?
This worked for me.这对我有用。 I renamed the MyApp StatefulWidget to Home and created a StatelessWidget and named it as MyApp .
我将MyApp StatefulWidget 重命名为Home并创建了一个 StatelessWidget 并将其命名为MyApp 。 Then I passed the Home StatefulWidget to the home attribute of MyApp StatelessWidget.
然后我将Home StatefulWidget 传递给MyApp StatelessWidget 的 home 属性。
import 'package:flutter/material.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';
import 'package:geolocator/geolocator.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(home: Home());
}
}
class Home extends StatefulWidget {
@override
_HomeState createState() => _HomeState();
}
class _HomeState extends State<Home> {
GoogleMapController mapController;
Position currentLocation;
LatLng _center;
Set<Marker> _markers = Set();
@override
void initState() {
// TODO: implement initState
super.initState();
setLocation();
}
void _onMapCreated(GoogleMapController controller) {
mapController = controller;
}
void setLocation() async {
currentLocation = await Geolocator()
.getCurrentPosition(desiredAccuracy: LocationAccuracy.high);
setState(() {
_center = LatLng(currentLocation.latitude, currentLocation.longitude);
});
}
Widget googleMap() {
addMarkers();
return GoogleMap(
onMapCreated: _onMapCreated,
myLocationEnabled: true,
initialCameraPosition: CameraPosition(
target: _center,
),
markers: _markers,
);
}
void addMarkers() {
_markers.addAll([
Marker(
markerId: MarkerId('current location'),
position: _center,
onTap: () {
print("tapped !!!!!!");
showModalBottomSheet(
context: context,
builder: (context) {
return Center(
child: Text('Modal bottom sheet',
style: TextStyle(fontSize: 30)),
);
});
},
),
]);
}
@override
Widget build(BuildContext context) {
print("Debug: build called!!!");
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('Google Map'),
backgroundColor: Colors.blue,
),
body: (_center == null)
? Center(child: CircularProgressIndicator())
: googleMap(),
),
);
}
}
I solve this problem using returning google map widget inside Builder & referencing the builder context我使用在 Builder 中返回 google map 小部件并引用构建器上下文来解决这个问题
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';
import 'package:geolocator/geolocator.dart';
import 'package:android_intent/android_intent.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
GoogleMapController mapController;
LatLng _currentPosition;
Set<Marker> _markers = Set();
// Obtaining current location coordinate & setting it
void setLocation() async {
bool isLocationEnabled = await Geolocator().isLocationServiceEnabled();
if(!isLocationEnabled){
openLocationSetting();
}
Position currentLocation = await Geolocator()
.getCurrentPosition(desiredAccuracy: LocationAccuracy.high);
setState(() {
_currentPosition =
LatLng(currentLocation.latitude, currentLocation.longitude);
});
}
// Open Location Setting if GPS not enabled
void openLocationSetting() async {
final AndroidIntent intent = new AndroidIntent(
action: 'android.settings.LOCATION_SOURCE_SETTINGS',
);
await intent.launch();
}
// initializing _currentPosition state.
@override
void initState() {
// TODO: implement initState
super.initState();
// Initiate full screen
SystemChrome.setEnabledSystemUIOverlays([]);
// Initiate current location
setLocation();
}
void showModal(BuildContext context) {
final _formKey = GlobalKey<FormState>();
final nameController = TextEditingController();
final locationController = TextEditingController();
locationController.text = _currentPosition.latitude.toString() +
"," +
_currentPosition.longitude.toString();
// Showing modal with Name & Current location input form to send data to console
showModalBottomSheet(
context: context,
isScrollControlled: true,
builder: (BuildContext context) {
return SingleChildScrollView(
child: Container(
padding: EdgeInsets.only(
bottom: MediaQuery.of(context).viewInsets.bottom),
child: Form(
key: _formKey,
child: Wrap(
children: <Widget>[
TextFormField(
decoration: InputDecoration(
hintText: 'Enter your current location',
),
controller: locationController,
validator: (value) {
if (value.isEmpty) {
return 'Please enter some text';
}
return null;
},
),
TextFormField(
decoration: InputDecoration(
hintText: 'Enter your name',
),
controller: nameController,
validator: (value) {
if (value.isEmpty) {
return 'Please enter some text';
}
return null;
},
),
RaisedButton(
onPressed: () {
if (_formKey.currentState.validate()) {
debugPrint(nameController.text);
debugPrint(locationController.text);
}
},
child: Text('Send'),
)
],
),
),
));
});
}
void _onMapCreated(GoogleMapController controller) {
mapController = controller;
}
// Adding markers in Google map for current location
void addMarkers(BuildContext context) {
_markers.addAll([
Marker(
markerId: MarkerId('Current Location'),
position: _currentPosition,
onTap: () {
showModal(context);
},
),
]);
}
// Building Google map widget & pointing initial position to current position
Widget googleMap(BuildContext context) {
addMarkers(context);
return GoogleMap(
onMapCreated: _onMapCreated,
myLocationEnabled: true,
initialCameraPosition: CameraPosition(
target: _currentPosition,
),
markers: _markers,
);
}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('Google Map'),
backgroundColor: Colors.teal,
),
body: Builder(
builder: (context) {
return (_currentPosition == null)
? Center(child: CircularProgressIndicator(),)
: googleMap(context);
},
)),
);
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.