在抖动中更新地图的相对位置

问题描述

您好,下面的代码使用google_maps_Flutter和location软件包显示了具有用户位置的地图,下面的代码正确显示了具有经度和纬度初始位置的地图,但是当用户从设备启动应用程序时,该位置不会它成为实际的用户之一,但仍停留在初始位置,我该如何解决呢?

Flutter代码

import 'dart:async';

import 'package:Flutter/material.dart';
import 'package:google_maps_Flutter/google_maps_Flutter.dart';
import 'package:location/location.dart';
import 'package:MyApp/View/Cantieri/mediterranesn_diet_view.dart'
    show MediterranesnDietView;
import 'package:MyApp/View/Cantieri/title_view.dart' show TitleView;
import 'package:MyApp/View/Home_theme.dart';
import 'package:MyApp/View/marcaTempo/FunzionemarcatempoView.dart'
    show marcaTempoListView;

//Valori longitudine e latitudine
double longitudine = 12.4818,latitudine = 41.9109;
LatLng _center = LatLng(latitudine,longitudine);
//Recupero e salvataggio dei valori del gps di longitudine e latitudine
Future<void> _getGpsValue() async {
  //Instanzio l'oggetto che si occupa di recuperare i dati per la marcatura
  var location = new Location();
  location.onLocationChanged().listen((LocationData currentLocation) async {
    longitudine = currentLocation.longitude;
    latitudine = currentLocation.latitude;
    _center = LatLng(latitudine,longitudine);
  });
  Timer(Duration(seconds: 1),() {
    print("E' passato 1 secondo");
    print("Latitudine: " +
        latitudine.toString() +
        "\n Longitudine: " +
        longitudine.toString());
  });
}

class MyDiaryScreen extends StatefulWidget {
  const MyDiaryScreen({Key key,this.animationController}) : super(key: key);

  final AnimationController animationController;

  @override
  _MyDiaryScreenState createState() => _MyDiaryScreenState();
}

class _MyDiaryScreenState extends State<MyDiaryScreen>
    with TickerProviderStateMixin {
  GoogleMapController mapController;
  var width;

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

  List<Widget> listViews = <Widget>[];
  final ScrollController scrollController = ScrollController();
  Animation<double> topBaranimation;
  double topBarOpacity = 0.0;

  @override
  void initState() {
    _getGpsValue();
    topBaranimation = Tween<double>(begin: 0.0,end: 1.0).animate(
        CurvedAnimation(
            parent: widget.animationController,curve: Interval(0,0.5,curve: Curves.fastOutSlowIn)));
    addAllListData();

    scrollController.addListener(() {
      if (scrollController.offset >= 24) {
        if (topBarOpacity != 1.0) {
          setState(() {
            topBarOpacity = 1.0;
          });
        }
      } else if (scrollController.offset <= 24 &&
          scrollController.offset >= 0) {
        if (topBarOpacity != scrollController.offset / 24) {
          setState(() {
            topBarOpacity = scrollController.offset / 24;
          });
        }
      } else if (scrollController.offset <= 0) {
        if (topBarOpacity != 0.0) {
          setState(() {
            topBarOpacity = 0.0;
          });
        }
      }
    });
    super.initState();
  }

  void addAllListData() {
    _getGpsValue();
    const int count = 9;

    //Prima view che comprende il titolo della Posizione
    listViews.add(
      TitleView(
        titleTxt: 'Posizione',subTxt: '',animation: Tween<double>(begin: 0.0,end: 1.0).animate(CurvedAnimation(
            parent: widget.animationController,curve:
                Interval((1 / count) * 0,1.0,curve: Curves.fastOutSlowIn))),animationController: widget.animationController,),);
    //Inserimento del modulo con le informazioni sulla posizione
    listViews.add(
      MediterranesnDietView(
        animation: Tween<double>(begin: 0.0,curve:
                Interval((1 / count) * 1,);

    //Inserimento del titolo di registrazione
    listViews.add(
      TitleView(
        titleTxt: 'Registrazione',curve:
                Interval((1 / count) * 2,);

    //Inserimento dei button per il marcatempo
    listViews.add(
      marcaTempoListView(
        mainScreenAnimation: Tween<double>(begin: 0.0,end: 1.0).animate(
            CurvedAnimation(
                parent: widget.animationController,curve: Interval((1 / count) * 3,mainScreenAnimationController: widget.animationController,);

    //Inserimento del titolo di registrazione
    listViews.add(
      TitleView(
        titleTxt: 'Mappa',);

    listViews.add(new Container(
        width: width,height: 400.0,child: GoogleMap(
            onMapCreated: _onMapCreated,initialCameraPosition: CameraPosition(
              target: _center,zoom: 6.0,))));
  }

  Future<bool> getData(BuildContext context) async {
    await Future<dynamic>.delayed(const Duration(milliseconds: 50));
    width = MediaQuery.of(context).size.width;
    return true;
  }

  Widget getMainListViewUI() {
    return FutureBuilder<bool>(
      future: getData(context),builder: (BuildContext context,AsyncSnapshot<bool> snapshot) {
        if (!snapshot.hasData) {
          return const SizedBox();
        } else {
          return ListView.builder(
            shrinkWrap: true,controller: scrollController,padding: EdgeInsets.only(
              top: AppBar().preferredSize.height +
                  MediaQuery.of(context).padding.top +
                  24,bottom: 62 + MediaQuery.of(context).padding.bottom,itemCount: listViews.length,scrollDirection: Axis.vertical,itemBuilder: (BuildContext context,int index) {
              widget.animationController.forward();
              return listViews[index];
            },);
        }
      },);
  }

//Recupero della barra per la UI
  Widget getAppBarUI() {
    return Column(
      children: <Widget>[
        AnimatedBuilder(
          animation: widget.animationController,Widget child) {
            return FadeTransition(
              opacity: topBaranimation,child: Transform(
                transform: Matrix4.translationValues(
                    0.0,30 * (1.0 - topBaranimation.value),0.0),child: Container(
                  decoration: Boxdecoration(
                    color: TemaApp.white.withOpacity(topBarOpacity),borderRadius: const BorderRadius.only(
                      bottomLeft: Radius.circular(32.0),BoxShadow: <BoxShadow>[
                      BoxShadow(
                          color: TemaApp.grey.withOpacity(0.4 * topBarOpacity),offset: const Offset(1.1,1.1),blurRadius: 10.0),],child: Column(
                    children: <Widget>[
                      SizedBox(
                        height: MediaQuery.of(context).padding.top,Padding(
                        padding: EdgeInsets.only(
                            left: 16,right: 16,top: 16 - 8.0 * topBarOpacity,bottom: 12 - 8.0 * topBarOpacity),child: Row(
                          mainAxisAlignment: MainAxisAlignment.center,children: <Widget>[
                            Expanded(
                              child: Padding(
                                padding: const EdgeInsets.all(8.0),child: Text(
                                  'marcatempo',textAlign: TextAlign.left,style: TextStyle(
                                    fontFamily: TemaApp.fontName,fontWeight: FontWeight.w700,fontSize: 22 + 6 - 6 * topBarOpacity,letterSpacing: 1.2,color: TemaApp.darkerText,)
                    ],);
          },)
      ],);
  }

  @override
  Widget build(BuildContext context) {
    return Container(
      color: TemaApp.background,child: Scaffold(
        backgroundColor: Colors.transparent,resizetoAvoidBottomPadding: true,body: Stack(
          children: <Widget>[
            //getMap(),getMainListViewUI(),getAppBarUI(),SizedBox(
              height: MediaQuery.of(context).padding.bottom,)
          ],);
  }
}

解决方法

您需要在setState()内部致电_getGpsValue()来更新用户的位置。

setState(() {
longitudine = currentLocation.longitude;
    latitudine = currentLocation.latitude;
    _center = LatLng(latitudine,longitudine);
})

根据documentation

调用setState会通知框架内部状态 该对象的更改方式可能会影响用户界面 在此子树中,这将导致框架为 这个State对象。