【问题标题】:Marker onTap property not updating the UI标记 onTap 属性未更新 UI
【发布时间】:2022-01-21 14:03:03
【问题描述】:

我正在尝试实施 Google 地图。当用户移动到地图页面并单击任何标记时,它不会更新卡上的数据。我认为它显示了标记列表的最后一个成员的数据。 谁能告诉我我在这里错过了什么。但是,当我点击任何其他位置时,它会在该位置添加标记并将其显示在卡片上。

import 'package:flutter/material.dart';
import 'package:geocoding/geocoding.dart';
import 'package:geolocator/geolocator.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';
import 'package:smart_car_parking/Models/Customer%20DSCC/CustomerDSCC.dart';
import 'package:smart_car_parking/Widgets/app_bar.dart';
import 'package:smart_car_parking/constants.dart';
import 'package:smart_car_parking/size_config.dart';
import 'package:maps_launcher/maps_launcher.dart';

class Mapss extends StatefulWidget {
  final List<CustomerDscc>? dsccList;
  final Position? position;
  Mapss({@required this.dsccList, @required this.position});
  @override
  _MapssState createState() => _MapssState();
}

class _MapssState extends State<Mapss> {
  bool isVisible = false;
  LatLng? _initialcameraposition;
  GoogleMapController? _controller;
  Set<Marker> _markers = {};
  LatLng? selectedPos;
  String? address;

  addMarker() {
    for (var dscc in widget.dsccList!) {
      if (dscc.latitude == null || dscc.latitude == "") {
      } else {
        //
        double lat = double.parse(dscc.latitude);
        double lng = double.parse(dscc.longitude);

        //
        print("=========================================");
        print("$lat + $lng");
        print("=========================================");

        //
        _markers.add(Marker(
            infoWindow: InfoWindow(title: dscc.nameCc),
            markerId: MarkerId('sourcePin'),
            position: LatLng(lat, lng),
            icon: BitmapDescriptor.defaultMarker,
            onTap: () {
              setState(() {
                isVisible = false;
              });

              setState(() {
                address = dscc.nameCc;
                selectedPos = LatLng(lat, lng);
                isVisible = true;
                print(selectedPos);
                print(address);
              });
            }));
      }
    }
  }

  markerTap({@required String? address, @required LatLng? pos}) {
    setState(() {
      isVisible = false;
    });

    setState(() {
      address = address;
      selectedPos = pos;
      isVisible = true;
      print(selectedPos);
      print(address);
    });
  }

  @override
  void initState() {
    _initialcameraposition =
        LatLng(widget.position!.latitude, widget.position!.longitude);
    setState(() {
      addMarker();
    });
    super.initState();
  }

  void _onMapCreated(GoogleMapController _cntlr) {
    _controller = _cntlr;
    _controller!.animateCamera(
      CameraUpdate.newCameraPosition(
        CameraPosition(
            // ignore: unnecessary_null_comparison
            target: _initialcameraposition!,
            zoom: 12),
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    SizeConfig().init(context);
    return Scaffold(
      appBar: customAppBar("Maps", true),
      backgroundColor: kPrimaryColor,
      body: customBody(),
    );
  }

  customBody() {
    return Container(
      margin: EdgeInsets.only(top: 10),
      width: double.infinity,
      height: SizeConfig.screenHeight,
      decoration: BoxDecoration(
        color: Colors.white,
        borderRadius: BorderRadius.vertical(top: Radius.elliptical(40, 40)),
      ),
      child: ClipRRect(
        borderRadius: BorderRadius.vertical(top: Radius.elliptical(40, 40)),
        child: Stack(children: [
          GoogleMap(
            initialCameraPosition:
                CameraPosition(target: _initialcameraposition!, zoom: 10),
            mapType: MapType.hybrid,
            onMapCreated: _onMapCreated,
            myLocationEnabled: true,
            markers: _markers,
            mapToolbarEnabled: false,
            indoorViewEnabled: true,
            trafficEnabled: true,
            onTap: onTap,
          ),
          isVisible ? infoWidget() : Container()
        ]),
      ),
    );
  }

  infoWidget() {
    return Align(
      alignment: Alignment.bottomCenter,
      child: Padding(
        padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 20),
        child: Container(
          width: double.infinity,
          height: getProportionateScreenHeight(80),
          child: Card(
            elevation: 10,
            shape:
                RoundedRectangleBorder(borderRadius: BorderRadius.circular(50)),
            child: Padding(
              padding: const EdgeInsets.symmetric(horizontal: 10),
              child: Row(
                children: [
                  Padding(
                    padding: EdgeInsets.fromLTRB(10, 10, 10, 10),
                    child: FittedBox(
                      child: Column(
                        mainAxisAlignment: MainAxisAlignment.spaceBetween,
                        children: [
                          Container(
                            width: getProportionateScreenWidth(230),
                            child: Text(
                              '$address',
                              style: TextStyle(fontWeight: FontWeight.bold),
                              maxLines: 2,
                              overflow: TextOverflow.ellipsis,
                            ),
                          ),
                          Container(
                            width: getProportionateScreenWidth(230),
                            child: Text(
                              'Latitude:  ${selectedPos!.latitude}',
                              maxLines: 2,
                              overflow: TextOverflow.ellipsis,
                            ),
                          ),
                          Container(
                            width: getProportionateScreenWidth(230),
                            child: Text(
                              'Longitude: ${selectedPos!.longitude}',
                              maxLines: 2,
                              overflow: TextOverflow.ellipsis,
                            ),
                          ),
                        ],
                      ),
                    ),
                  ),
                  Spacer(),
                  FloatingActionButton(
                    child: Icon(Icons.directions_rounded),
                    onPressed: () {
                      MapsLauncher.launchCoordinates(
                          selectedPos!.latitude, selectedPos!.longitude);
                    },
                  )
                ],
              ),
            ),
          ),
        ),
      ),
    );
  }

  void onTap(LatLng pos) {
    _getAddressFromLatLng(pos).then((addresss) {
      setState(() {
        selectedPos = pos;
        address = addresss;
        _markers.add(Marker(
          infoWindow: InfoWindow(title: addresss),
          markerId: MarkerId('sourcePin'),
          position: LatLng(pos.latitude, pos.longitude),
          icon: BitmapDescriptor.defaultMarker,
        ));
        isVisible = true;
      });
    });
  }

  Future<String> _getAddressFromLatLng(LatLng pos) async {
    List<Placemark> placemarks =
        await placemarkFromCoordinates(pos.latitude, pos.longitude);

    Placemark place = placemarks[0];

    return "${place.street}, ${place.subLocality}, ${place.locality}";
  }
}

【问题讨论】:

  • 一些可能有帮助的观察结果:1)您在开始时添加的标记的 markerId 是相同的('sourcePin'),我相信这将导致只添加一个标记; 2) 您连续调用 setState(),这可能不是问题,但不需要; 3) 使用地址既作为实例字段又作为局部变量使用是混乱和容易出错的; 4) 最好在点击标记时将 InfoWidget 创建为单独的无状态小部件,并使用“isVisible”控制该小部件的可见性。
  • 感谢兄弟拯救了我的一天。问题是我提供的数据相同('sourcePin)。

标签: flutter google-maps dart google-maps-markers


【解决方案1】:

归功于Bram。我对所有人都使用相同的('sourcePin'),所以现在我为他们提供了独特的解决方案。

【讨论】:

    猜你喜欢
    • 2011-09-16
    • 1970-01-01
    • 2017-06-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-02
    • 1970-01-01
    相关资源
    最近更新 更多