Функция нажатия кнопок флаттера постоянно вызывается при создании или задании состояния - PullRequest
2 голосов
/ 19 мая 2019

Я использую плагин Google Maps и у меня есть кнопка, которая добавляет маркер на карту.

Проблема заключается в том, что при первой загрузке экрана функция кнопки (_onAddMarkerButtonPressed) вызывается сразу и устанавливает маркер на карте. Я предполагаю, что это из метода createSate ().

У меня также есть текстовое представление, которое обновляется новым адресом на карте при каждом перемещении карты (_onCameraMove). Это вызывает setState () после изменения значения String, которое отображается в этом текстовом виджете. Однако это не только обновление текста, но и вызов _onAddMarkerButtonPressed и добавление нового маркера при каждом перемещении камеры на карте. Так что я заканчиваю скринингом маркеров.

Спасибо за вашу помощь.

 class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);
  final String title;

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

class _MyHomePageState extends State<MyHomePage> {

  Completer<GoogleMapController> _controller = Completer();
  static const LatLng _center  = const LatLng(-31.950260, 115.851840);
  final Set<Marker> _markers = {};
  LatLng _lastMapPosition = _center;

  @override
  Widget build(BuildContext context) {

    double mapWidth = MediaQuery.of(context).size.width;
    double mapHeight = MediaQuery.of(context).size.height - 215;
    double iconSize = 30.0;

    return Scaffold(
      appBar: AppBar(

        title: Text(widget.title),
      ),
      body: Stack(
        alignment: Alignment(0.0, 0.0),
        children: <Widget>[
          GoogleMap(
            onMapCreated: _onMapCreated,
            initialCameraPosition: CameraPosition(target: _center, zoom: 16.0),
            mapType: MapType.normal,
            markers: _markers,
            onCameraMove: _onCameraMove,
          ),

          Positioned(
            top: 0,
            child: Padding(
              padding: const EdgeInsets.all(16.0),
              child: Container(
                  decoration: BoxDecoration( borderRadius: BorderRadius.circular(10.0), color: Colors.white),
                  height: 75,
                  width: mapWidth,
                  child: Center(
                      child: Text(address))),
            ),
          ),

         Positioned(
          top: (mapHeight - iconSize)/ 2,
          right: (mapWidth - iconSize)/ 2,
          child: Icon(Icons.my_location, size: iconSize, color: Colors.black87,),
        ),

         Positioned(
           bottom: 24.0,
           left: 24.0,
           child: Icon(Icons.search, size: 40, color: Colors.blue,) ,
        ),

          Positioned(
            bottom: 24.0 - (42/2),
            right: (mapWidth - 150)/ 2,
            child: RoundedButton(title: 'Add Alert', color: Colors.lightBlueAccent, onPressed: _onAddMarkerButtonPressed()),
          ),

        Positioned(
          bottom: 24.00,
          right: 24.0,
          child: Icon(Icons.my_location, size: 40, color: Colors.blue,) ,
        ),
      ],
    ),
  );
}


  _onAddMarkerButtonPressed (){
    setState(() {
      _markers.add(Marker(
          markerId: MarkerId(_lastMapPosition.toString()),
          position: _lastMapPosition,
          infoWindow: InfoWindow(
            title: 'This is the title',
            snippet: 'This is the snippet',
          ),
          icon: BitmapDescriptor.defaultMarker,
        ),
      );
    });
  }

  _onCameraMove(CameraPosition position) async{
    _lastMapPosition = position.target;
    final coordinates = new Coordinates(position.target.latitude, position.target.longitude);
    var addresses = await Geocoder.local.findAddressesFromCoordinates(coordinates);
    var first = addresses.first;

    setState(() {
      address = "${first.addressLine}";
    });
  }

1 Ответ

1 голос
/ 19 мая 2019

Ваша ошибка в этой строке onPressed: _onAddMarkerButtonPressed()

, так как вы исключаете свою функцию всякий раз, когда этот виджет отображается в виде

, вы должны передать его внутрь функции стрелки, подобной этой

onPressed: () => _onAddMarkerButtonPressed()

...