我正在使用这个Marker的onTap()方法在按下Google Maps的标记(当前位置)之后显示一个 showModalBottomSheet 小部件。但它显示异常: 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(),
),
);
}
}
我该如何解决?
答案 0 :(得分:1)
这对我有用。我将 MyApp StatefulWidget重命名为 Home ,并创建了一个StatelessWidget并将其命名为 MyApp 。然后,将 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(),
),
);
}
}
答案 1 :(得分:0)
我通过在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);
},
)),
);
}
}