【问题标题】:Flutter build method is being called before the variables are fully initialized which is causing app crashes在变量完全初始化之前调用 Flutter build 方法,这会导致应用程序崩溃
【发布时间】:2025-12-31 18:35:02
【问题描述】:

我想从会话变量中初始化 _lastMapPosition 的值,但在我的情况下,builds 方法在 intistate 方法之前运行。在构建小部件方法之前有没有一种简单的方法来初始化它?我是新来的颤振,请提供完整的细节。我已经尝试过futurebuilder,但我想我都尝试错了。

import 'dart:async';
    import 'package:flutter/material.dart';
    import 'package:google_maps_flutter/google_maps_flutter.dart';
    import 'package:permission/permission.dart';
    import 'package:flutter_session/flutter_session.dart';
    class GmyApp extends StatefulWidget {
      const GmyApp({Key key}) : super(key: key);
      @override
      _GmyApp createState() => _GmyApp();
    }
    class _GmyApp extends State<GmyApp> {
      var latitude_data;
      var longitude_data;
      Completer<GoogleMapController> _controller = Completer();
      static const LatLng _center = const LatLng(10.8505, 76.2711);
      final Set<Marker> _markers = {};
      LatLng _lastMapPosition= _center;
      MapType _currentMapType = MapType.normal;
      void _onMapTypeButtonPressed() {
        setState(() {
          _currentMapType = _currentMapType == MapType.normal
              ? MapType.satellite
              : MapType.normal;
        });
      }
      void _onAddMarkerButtonPressed() {
        setState(() {
          _markers.add(Marker(
            // This marker id can be anything that uniquely identifies each marker.
            markerId: MarkerId(_lastMapPosition.toString()),
            position: _lastMapPosition,
            infoWindow: InfoWindow(
              title: 'Your last location',
              snippet: 'Location Refreshed every 1 hour',
            ),
            icon: BitmapDescriptor.defaultMarker,
          ));
        });
      }
      void _onCameraMove(CameraPosition position) {
        _lastMapPosition = position.target;
      }
      void _onMapCreated(GoogleMapController controller) {
        _controller.complete(controller);
      }
      @override
      void initState() {
        // TODO: implement initState
        super.initState();
        setGps();
      }
      Future setGps() async {
        bool visible = false;
        print('I am in GPS setter*');
        // var session = FlutterSession();
        latitude_data = await FlutterSession().get('lat');
        longitude_data = await FlutterSession().get('longi');
        print('User logi Id is in GPS* $longitude_data');
        print('User lat is in GPS* $latitude_data');
        LatLng center1=LatLng(latitude_data, longitude_data);
        print('Lat .lat is in GPS  $center1');
         _lastMapPosition = center1;
        print('Lat .lat lastMap Position is  $_lastMapPosition');
      }
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          home: Scaffold(
            appBar: AppBar(
              title: Text('Your Current Location is'),
              backgroundColor: Colors.green[700],
            ),
            body: Stack(
              children: <Widget>[
                GoogleMap(
                  onMapCreated: _onMapCreated,
                  initialCameraPosition: CameraPosition(
                    target: _lastMapPosition,
                    zoom: 11.0,
                  ),
                  mapType: _currentMapType,
                  markers: _markers,
                  onCameraMove: _onCameraMove,
                ),
                Padding(
                  padding: const EdgeInsets.all(16.0),
                  child: Align(
                    alignment: Alignment.topRight,
                    child: Column(
                      children: <Widget> [
                        FloatingActionButton(
                          onPressed: _onMapTypeButtonPressed,
                          heroTag: "btn1",
                          materialTapTargetSize: MaterialTapTargetSize.padded,
                          backgroundColor: Colors.green,
                          child: const Icon(Icons.map, size: 36.0),
                        ),
                        SizedBox(height: 16.0),
                        FloatingActionButton(
                          onPressed: _onAddMarkerButtonPressed,
                          heroTag: "btn2",
                          materialTapTargetSize: MaterialTapTargetSize.padded,
                          backgroundColor: Colors.green,
                          child: const Icon(Icons.add_location, size: 36.0),
                        ),
                      ],
                    ),
                  ),
                ),
              ],
            ),
          ),
        );
      }
    }

【问题讨论】:

    标签: flutter android-studio dart build widget


    【解决方案1】:

    因为您的数据是异步加载的,所以会在您的数据加载之前调用 build。

    有一些解决方案最好是使用状态管理解决方案,然后检查数据的当前状态以显示或隐藏相关小部件。

    但为了快速修复,您可以将 _lastMapPosition 设为可空 LatLng? _lastMapPosition; 并且不给它一个初始值,然后在 GoogleMap 小部件之前检查数据是否已加载,如果没有显示加载指示器

    [ 
      if(_lastMapPosition != null)
      GoogleMap(
        onMapCreated: _onMapCreated,
        initialCameraPosition: CameraPosition(
          target: _lastMapPosition!,
          zoom: 11.0,
        ),
        ...
      ),
      if(_lastMapPosition == null)
      Center(child: CircularProgressIndicator()),
    ]
    

    现在,当您的数据在 setGps 中加载时,请使用 setState 使用新数据重建用户界面

    setState((){
      _lastMapPosition = center1;
    });
    

    我仍然建议使用状态管理解决方案,它可以使您的代码更具可读性和可预测性

    【讨论】:

      【解决方案2】:

      只需在 setGps() 方法中添加 setState 方法

            Future setGps() async {
          bool visible = false;
          print('I am in GPS setter*');
          // var session = FlutterSession();
          latitude_data = await FlutterSession().get('lat');
          longitude_data = await FlutterSession().get('longi');
          print('User logi Id is in GPS* $longitude_data');
          print('User lat is in GPS* $latitude_data');
          LatLng center1=LatLng(latitude_data, longitude_data);
          print('Lat .lat is in GPS  $center1');
           _lastMapPosition = center1;
          print('Lat .lat lastMap Position is  $_lastMapPosition');
          setState(() {});
        }
      

      【讨论】:

        最近更新 更多