【问题标题】:Unhandled Exception: No MediaQuery widget found - flutter ShowModalButtonSheet未处理的异常:未找到 MediaQuery 小部件 - 颤振 ShowModalButtonSheet
【发布时间】:2020-12-29 19:41:49
【问题描述】:

我正在做这个项目,在按下谷歌地图的标记(当前位置)后显示一个 showModalBottomSheet 小部件,使用标记的 onTap() 方法。但它显示异常: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(),

      ),

    );
  }
}

我该如何解决这个问题?

【问题讨论】:

  • 你能发布完整的错误日志吗?
  • E/flutter (25672): [ERROR:flutter/lib/ui/ui_dart_state.cc(166)] 未处理异常:未找到 MediaQuery 小部件。 E/flutter (25672):MyApp 小部件需要 MediaQuery 小部件祖先。 E/flutter (25672):找不到 MediaQuery 祖先的特定小部件是:E/flutter (25672):MyApp E/flutter (25672):受影响小部件的所有权链是:“MyApp ← [root]” E/flutter (25672):通常,MediaQuery 小部件由应用程序小部件树顶部的 MaterialApp 或 WidgetsApp 小部件引入。

标签: android google-maps flutter


【解决方案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(),
      ),
    );
  }
}

【讨论】:

  • 非常感谢!你能解释一下为什么我的代码会出现这样的问题吗?
  • 不客气@Roslin!我对您的问题没有明确的答复,但据我所知,ShowModalButtonSheet 不应与 MaterialApp 处于同一级别,因此我尝试将它们分开,它对我有用
  • 如果我的回答也对您有用并且有帮助,请接受它。谢谢!
【解决方案2】:

我使用在 Builder 中返回 google map 小部件并引用 builder 上下文解决了这个问题

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);
            },
          )),
    );
  }
}

【讨论】:

    猜你喜欢
    • 2019-11-27
    • 2020-06-29
    • 2019-10-05
    • 2021-12-18
    • 2020-12-05
    • 2021-10-08
    • 2022-01-05
    • 2021-03-31
    • 1970-01-01
    相关资源
    最近更新 更多