Flutter自定义GoogleMap可拖动标记使用Lottie

piah890a  于 2023-08-07  发布在  Flutter
关注(0)|答案(1)|浏览(163)

下面是我全部代码,以便其他人可以看到并复制。
现在的问题是**_getCustomPin()正在阻止拖动,或者当我开始拖动自定义引脚时,它不会拖动,但当我拖动时,它不会拖动自定义引脚,然后它会拖动oncameramove
它也关闭与我的位置指示器,但当我设置宽度和高度的定制为50它适合,但它太小,因此150
下面是
_getCustomPIN()**https://github.com/IAMZenju/StackOverFlowFiles/blob/main/files/RedMarkerPIN.json中使用的lottie文件
请帮助我,我只是想实现的DoorDash拖动标记效果的原因使用默认的色调红色的原因口吃
谢谢大家,祝福大家<3

import 'dart:async';
import 'package:flutter/material.dart';
import 'package:geocoding/geocoding.dart';
import 'package:geolocator/geolocator.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart' as maps;
import 'package:flutter_speed_dial/flutter_speed_dial.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:lottie/lottie.dart';


class LocationChangerV1 extends StatefulWidget {
  const LocationChangerV1({Key? key}) : super(key: key);

  @override
  State<LocationChangerV1> createState() => _LocationChangerV1State();
}

class _LocationChangerV1State extends State<LocationChangerV1> {
  String _latitude = 'Unknown';
  String _longitude = 'Unknown';
  String _draggedAddress = "Unknown";

  maps.LatLng _selectedLatLng = maps.LatLng(0, 0); // Default initial LatLng

  late maps.GoogleMapController _mapController;

  @override
  void initState() {
    //addCustomIcon();
    super.initState();
    _getLocation();
  }

  Future<void> _getLocation() async {
    try {
      Position position = await Geolocator.getCurrentPosition(
        desiredAccuracy: LocationAccuracy.high,
      );
      setState(() {
        _latitude = position.latitude.toString();
        _longitude = position.longitude.toString();
        _selectedLatLng = maps.LatLng(position.latitude, position.longitude);
      });
      _getAddress(position.latitude, position.longitude);

    } catch (e) {
      debugPrint("Error while fetching location: $e");
      setState(() {
        _latitude = 'Error';
        _longitude = 'Error';
        // Set the default location if getting current location fails
        _selectedLatLng = maps.LatLng(10.308896831229562, 123.71293251977808);
      });
      _getAddress(10.308896831229562, 123.71293251977808);
    }
  }

  
  Future<void> _getAddress(double latitude, double longitude) async {
  try {
      List<Placemark> placemarks = await placemarkFromCoordinates(latitude, longitude);

      if (placemarks.isNotEmpty) {
        Placemark address = placemarks.first;
        String street = address.street ?? ''; // Street name (if available)
        String barangay = address.subLocality ?? ''; // Barangay name (if available)
        String city = address.locality ?? ''; // City name (if available)
        String country = address.country ?? ''; // Country name (if available)
        String countryCode = address.isoCountryCode ?? ''; // Country code (if available)

        // Combine the address components into the desired format
        //String addressStr = "$street, $barangay, $city, $country, $countryCode";
        String addressStr = "$street, $barangay, $city, $countryCode";

        setState(() {
          _draggedAddress = addressStr;
        });
      }
    } catch (e) {
      setState(() {
        _draggedAddress = 'Unknown';
        debugPrint(e.toString());
      });
    }
  }

   Future<void> _waitForLocationUpdate() async {
    // Wait until the location is updated with a valid value (latitude and longitude other than 0,0)
    while (_selectedLatLng.latitude == 0 && _selectedLatLng.longitude == 0) {
      await Future.delayed(Duration(milliseconds: 500));
    }
  }
  
  //
  Future<void> _animateToCurrentLocation() async {
    try {
      Position position = await Geolocator.getCurrentPosition(
        desiredAccuracy: LocationAccuracy.high,
      );
      maps.LatLng currentLatLng = maps.LatLng(position.latitude, position.longitude);

      // ignore: unnecessary_null_comparison
      if (_mapController != null) {
        // Check if the map controller is not null before using it
        // Animate the camera to the user's current location
        _mapController.animateCamera(maps.CameraUpdate.newLatLngZoom(currentLatLng, 15.0));

        // Update the selectedLatLng and address with the new location
        setState(() {
          _selectedLatLng = currentLatLng;
        });
        //_updateAddress(position.latitude, position.longitude);
      }
    } catch (e) {
      debugPrint("Error while animating to current location: $e");
    }
  }
  
  void _changeMapType(maps.MapType mapType) {
    setState(() {
      _mapType = mapType;
    });
  }

  maps.MapType _mapType = maps.MapType.normal; // Initial map type is normal

  @override
  Widget build(BuildContext context) {
    return Material(
      color: Colors.white, // Set the background color to blue
      child: Scaffold(
        backgroundColor: Colors.white,
        appBar: AppBar(
          backgroundColor: const Color(0xFFB41F26),
          centerTitle: true,
          title: const Text(
            'Select Location',
            style: TextStyle(
              fontSize: 24,
              fontWeight: FontWeight.bold,
            ),
          ),
        ),
        body: Stack(
          alignment: Alignment.center,
          children: [
            _buildGoogleMap(),
            _getCustomPin(),
          ],
        ),

        floatingActionButtonLocation: FloatingActionButtonLocation.startFloat,
        //floatingActionButton: _buildSpeedDial(),
        floatingActionButton: Row(
        mainAxisAlignment: MainAxisAlignment.spaceBetween,
        children: [
           // Existing SpeedDial button on the left side
           _buildSpeedDial(),

          // New Location button on the right side
          Padding(
            padding: const EdgeInsets.only(right: 30.0),
            child: FloatingActionButton(
              onPressed: () {
                _animateToCurrentLocation();
              },
              backgroundColor: const Color(0xFFB41F26),
              child: Icon(Icons.location_on),
            ),
          ),
        ],
      ),

       
        persistentFooterButtons: [
          Row(
            mainAxisSize: MainAxisSize.max,
            children: [
              Expanded(
                child: Container(
                  width: double.infinity,
                  color: Colors.white,
                  padding: EdgeInsets.all(10.0),
                  child: Column(
                    mainAxisSize: MainAxisSize.min,
                    children: [
                      Text(
                        'Latitude: ${_selectedLatLng.latitude}',
                        style: TextStyle(
                          fontSize: 16.0,
                        ),
                      ),

                      SizedBox(height: 10),
                      Text(
                        'Longitude: ${_selectedLatLng.longitude}',
                        style: TextStyle(
                          fontSize: 16.0,
                        ),
                      ),

                      SizedBox(height: 10),
                      Text(
                        'Address: ${_draggedAddress}',
                        style: TextStyle(
                          fontSize: 12.0,
                        ),
                      ),

                    SizedBox(height: 10),
                      SizedBox(
                        width: double.infinity, // Make the button full width
                        child: ElevatedButton(
                          onPressed: () {
                            // Add the action you want to perform when the button is clicked
                            // For example, you can display a confirmation message or navigate to another screen.
                            // Replace this with your desired action.

                            debugPrint("Location Confirmed!");
                          },
                          style: ElevatedButton.styleFrom(
                            backgroundColor: const Color(0xFFB41F26), // Set the background color to const Color(0xFFB41F26)
                          ),
                          child: Text(
                            "Confirm Location",
                            style: TextStyle(fontSize: 14, color: Colors.white),
                          ),
                        ),
                      ),
                    ],
                  ),
                ),
              ),
            ],
          ),
        ],
        
        
      ),
    );
  }

  Widget _buildGoogleMap() {
    return maps.GoogleMap(
        mapType: _mapType,
        initialCameraPosition: maps.CameraPosition(
          zoom: 15.0,
          target: _selectedLatLng.latitude != 0 && _selectedLatLng.longitude != 0
              ? _selectedLatLng
              : const maps.LatLng(10.308896831229562, 123.71293251977808),
        ),
        onMapCreated: (maps.GoogleMapController controller) async {
          _mapController = controller;
          setState(() {
            _selectedLatLng = _selectedLatLng;
          });

          if (_selectedLatLng.latitude == 0 && _selectedLatLng.longitude == 0) {
            await _waitForLocationUpdate();
          }

          controller.animateCamera(maps.CameraUpdate.newLatLngZoom(_selectedLatLng, 15.0));
        },
        onCameraIdle: () {
          _getAddress(_selectedLatLng.latitude, _selectedLatLng.longitude);
          debugPrint('IM IDLE');
        },
        onCameraMove: (maps.CameraPosition position) {
          setState(() {
            _selectedLatLng = position.target;
          });
        },
        markers: {
          /*
          maps.Marker(
          markerId: const maps.MarkerId('selectedLocation'),
          position: _selectedLatLng,
          draggable: true,
          icon: maps.BitmapDescriptor.defaultMarkerWithHue(
                    maps.BitmapDescriptor.hueRed,
          )),
          */
        }, // Remove the Marker widget here
        mapToolbarEnabled: false,
        myLocationEnabled: true,
        myLocationButtonEnabled: false,
        zoomControlsEnabled: false,
        zoomGesturesEnabled: true,
    );
  }
  

Widget _getCustomPin() {
  return Align(
    alignment: Alignment.center,
    child: Container(
      width: 150,
      height: 150,
      child: Lottie.asset("assets/lottie/RedMarkerPIN.json"),
    ),
  );
}



  Widget _buildSpeedDial() {
    return SpeedDial(
      icon: Icons.layers,
      animatedIconTheme: IconThemeData(size: 22.0),
      overlayColor: Colors.black,
      overlayOpacity: 0.4,
      curve: Curves.easeInOut,
      foregroundColor: Colors.white,
      backgroundColor: const Color(0xFFB41F26),
      switchLabelPosition: true,
      children: [
        SpeedDialChild(
          child: Icon(Icons.map),
          onTap: () {
            _changeMapType(maps.MapType.normal);
          },
          label: 'Normal',
          labelStyle: TextStyle(fontSize: 14.0),
          foregroundColor: Colors.white,
          backgroundColor: const Color(0xFFB41F26),
        ),
        SpeedDialChild(
          child: Icon(Icons.satellite),
          onTap: () {
            _changeMapType(maps.MapType.satellite);
          },
          label: 'Satellite',
          labelStyle: TextStyle(fontSize: 14.0),
          foregroundColor: Colors.white,
          backgroundColor: const Color(0xFFB41F26),
        ),
        SpeedDialChild(
          child: Icon(Icons.terrain),
          onTap: () {
            _changeMapType(maps.MapType.terrain);
          },
          label: 'Terrain',
          labelStyle: TextStyle(fontSize: 14.0),
          foregroundColor: Colors.white,
          backgroundColor: const Color(0xFFB41F26),
        ),
        SpeedDialChild(
          child: Icon(Icons.layers),
          onTap: () {
            _changeMapType(maps.MapType.hybrid);
          },
          label: 'Hybrid',
          labelStyle: TextStyle(fontSize: 14.0),
          foregroundColor: Colors.white,
          backgroundColor: const Color(0xFFB41F26),
        ),
      ],
    );
    
  }
  

}

字符串

fsi0uk1n

fsi0uk1n1#

我花了好几个小时才解决这个问题我终于用这个解决了

Widget _getCustomPin() {
  // Define the desired offset in pixels (adjust these values as needed)
  double offsetX = 0;
  double offsetY = -20;

  return Transform.translate(
    offset: Offset(offsetX, offsetY),
    child: Center(
       child: IgnorePointer(
      ignoring: true, // Set this to true to allow touch events to pass through
        child: Container(
          width: 150,
          height: 150,
          child: Lottie.asset("assets/lottie/RedMarkerPIN.json"),
        ),
      ),  
    ),
  );
}

字符串

相关问题