【问题标题】:Flutter get user location real time error: The setter 'latitude' was called on nullFlutter 获取用户位置实时错误:setter 'latitude' was called on null
【发布时间】:2019-12-19 12:34:16
【问题描述】:

我是新手。我正在尝试获取用户位置的实时信息。为此,我使用了位置插件 (https://pub.dev/packages/location)。

问题是地图在分配位置之前被填充,并返回错误:

在 null 上调用了 setter 'latitude'。

这是主要的飞镖:

import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';
import 'dart:async';
import 'package:flutter/services.dart';
import 'package:location/location.dart';
import './models/userLocation.dart';

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

class Maps extends StatefulWidget {
  @override
  _MapsState createState() => _MapsState();
}

class _MapsState extends State<Maps> {

  LocationData currentLocation;

  UserLocation _currentLocation;



  var location = new Location();


  String error;


  void _onMapCreated(GoogleMapController controller) {
    mapController = controller;
  }
  GoogleMapController mapController;

  void initState() {
    super.initState();

    initMapState();


  }

  initMapState() async {
    try {
      var userLocation = await location.getLocation();
      _currentLocation = UserLocation(
        latitude: userLocation.latitude,
        longitude: userLocation.longitude,
      );

    } on PlatformException catch (e) {
      if (e.code == 'PERMISSION_DENIED') {
        error = 'Permission denied';
      }
      return _currentLocation;

    }

    location.onLocationChanged().listen((LocationData currentLocation) {
      print(currentLocation.latitude);
      print(currentLocation.longitude);

    });
  }

  @override
  Widget build(BuildContext context) {

    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('Create new trip'),
          backgroundColor: Colors.green[700],
        ),
        body: GoogleMap(
          onMapCreated: _onMapCreated,
          initialCameraPosition: CameraPosition(
            target:
                LatLng(_currentLocation?.latitude,_currentLocation?.longitude),
            zoom: 11.0,
          ),
        ),
      ),
    );
  }
}

以下是定位模型:

class UserLocation {
   double latitude;
   double longitude;
  UserLocation({this.latitude, this.longitude});
}

感谢您的支持。

谢谢,

编辑:

更新的工作文件:

import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';
import 'dart:async';
import 'package:flutter/services.dart';
import 'package:location/location.dart';
import './models/userLocation.dart';

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

class Maps extends StatefulWidget {
  @override
  _MapsState createState() => _MapsState();
}

class _MapsState extends State<Maps> {


  Location location = new Location();
  UserLocation userLocation;
  StreamSubscription<LocationData> positionSubscription;

  UserLocation _currentLocation;


  String error;


  void _onMapCreated(GoogleMapController controller) {
    mapController = controller;
  }
  GoogleMapController mapController;

  @override
  void initState() {
  super.initState();
  positionSubscription = location
      .onLocationChanged()
      .handleError((error) => print(error))
      .listen(
        (newPosition) => setState(() {
          _currentLocation = UserLocation(
            latitude: newPosition.latitude,
            longitude: newPosition.longitude,
          );
        }),
      );
}

@override
void dispose() {
  positionSubscription?.cancel();
  super.dispose();
}


  @override
  Widget build(BuildContext context) {

    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('Create new trip'),
          backgroundColor: Colors.green[700],
        ),
        body: GoogleMap(
          onMapCreated: _onMapCreated,
          initialCameraPosition: CameraPosition(
            target:
                LatLng(_currentLocation.latitude,_currentLocation.longitude),
            zoom: 11.0,
          ),
        ),
      ),
    );
  }
}

【问题讨论】:

    标签: flutter real-time-updates


    【解决方案1】:
    • 因此,由于您的 initState 未使用 @override,因此此方法是 不叫

    • 您不能在 onInit 回调中使用异步调用。这是错误的。再一次,你 错过了@override。

    • 根据文档,您无需致电 getLocation,因为您 已经订阅了位置信息。

    理想情况下,你需要这样的东西:

    UserLocation userPosition;
    StreamSubscription<LocationData> positionSubscription;
    
    @override
    void initState() {
      super.initState();
      positionSubscription = location
          .onLocationChanged()
          .handleError((error) => print(error))
          .listen(
            (newPosition) => setState(() {
              _currentLocation = UserLocation(
                latitude: newPosition.latitude,
                longitude: newPosition.longitude,
              );
            }),
          );
    }
    
    @override
    void dispose() {
      positionSubscription?.cancel();
      super.dispose();
    }
    

    【讨论】:

    • 感谢您的详细回复。但是,我在 positionSubscript 上收到此错误:“StreamSubscription”类型的值无法分配给“StreamSubscription 类型的变量
    • 您能否更新您的问题并单独添加此行?
    • 再次非常感谢..我所做的唯一更改是将流订阅类型更改为“LocationData”祝您有美好的一天;
    【解决方案2】:

    initMapState();之后写super.initState(),因为在调用super.initState()之后直接调用build(),不会等待initMapState()完成执行

    void initState() {
        initMapState();
        super.initState();
      }
    

    【讨论】:

    • 你不能这样做,因为你在你想调用initMapState的那一刻没有初始化基本小部件状态
    • 那么我们应该采用两种方法,一种用于在super.initState之前获取位置,另一种用于在super.initState之后进行地图初始化..
    • super.initState的位置没有问题。 > 如果您覆盖它,请确保您的方法以调用 super.initState() 开始。 api.flutter.dev/flutter/widgets/State/initState.html
    猜你喜欢
    • 1970-01-01
    • 2021-08-03
    • 2020-06-26
    • 1970-01-01
    • 1970-01-01
    • 2020-12-15
    • 1970-01-01
    • 2023-03-23
    • 2020-03-20
    相关资源
    最近更新 更多