Untitled

 avatar
user_6232722
plain_text
3 days ago
5.4 kB
1
Indexable
Never
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';
import 'map_controller.dart';

class MarkerItem {
  final int id;
  final double latitude;
  final double longitude;

  MarkerItem({
    required this.id,
    required this.latitude,
    required this.longitude,
  });
}

class InteractiveMapsMarker extends StatefulWidget {
  final LatLng center;
  final double itemHeight;
  final double zoom;
  final double zoomFocus;
  final bool zoomKeepOnTap;
  final Set<Marker> markers;
  final IndexedWidgetBuilder? itemContent;
  final IndexedWidgetBuilder? itemBuilder;
  final EdgeInsetsGeometry itemPadding;
  final Alignment contentAlignment;
  final InteractiveMapsController? controller;
  final VoidCallback? onLastItem;
  final Uint8List? markerIcon;
  final Uint8List? markerIconSelected;

  InteractiveMapsMarker({
    super.key,
    required this.markers,
    this.itemBuilder,
    this.center = const LatLng(0.0, 0.0),
    this.itemContent,
    this.itemHeight = 116.0,
    this.zoom = 12.0,
    this.zoomFocus = 15.0,
    this.zoomKeepOnTap = false,
    this.itemPadding = const EdgeInsets.only(bottom: 80.0),
    this.contentAlignment = Alignment.bottomCenter,
    this.controller,
    this.onLastItem,
    this.markerIcon,
    this.markerIconSelected,
  }) {
    if (itemBuilder == null && itemContent == null) {
      throw Exception('itemBuilder or itemContent must be provided');
    }
  }

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

class InteractiveMapsMarkerState extends State<InteractiveMapsMarker> {
  final Completer<GoogleMapController> _controller = Completer();
  GoogleMapController? mapController;
  final PageController pageController = PageController(viewportFraction: 1);
  final ValueNotifier<int?> selectedMarker = ValueNotifier<int?>(0);
  double mapRotation = 0;
  int currentIndex = 0;
  late LatLng currentLocation;
  double currentZoom = 0;

  @override
  void initState() {
    super.initState();
    // markers = widget.items
    //     .asMap()
    //     .map(
    //       (index, item) => MapEntry(
    //         index,
    //         Marker(
    //           markerId: MarkerId(item.id.toString()),
    //           position: LatLng(item.latitude, item.longitude),
    //           onTap: () {
    //             pageController.animateToPage(
    //               index,
    //               duration: const Duration(milliseconds: 500),
    //               curve: Curves.ease,
    //             );
    //           },
    //         ),
    //       ),
    //     )
    //     .values
    //     .toSet();
    currentLocation = widget.center;
    WidgetsBinding.instance.addPostFrameCallback((_) {
      // _zoomToCurrentMarker();
    });
  }

  @override
  void didChangeDependencies() {
    super.didChangeDependencies();
  }

  void _onMapCreated(GoogleMapController controller) async {
    mapController = controller;
    final mapStyle = await rootBundle.loadString('assets/json/map_style.json');
    mapController?.setMapStyle(mapStyle);
    _controller.complete(controller);
  }

  void _updateMapRotation(double newBearing) {
    mapController?.animateCamera(
      CameraUpdate.newCameraPosition(
        CameraPosition(
          target: currentLocation,
          zoom: currentZoom,
          bearing: newBearing,
        ),
      ),
    );
  }

  void _onCameraMove(CameraPosition position) {
    setState(() {
      mapRotation = position.bearing;
      currentLocation = position.target;
      currentZoom = position.zoom;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Stack(
      children: <Widget>[
        _buildMap(),
      ],
    );
  }

  Widget _buildMap() {
    return Positioned.fill(
      child: ValueListenableBuilder<int?>(
        valueListenable: selectedMarker,
        builder: (context, value, child) {
          return GoogleMap(
            zoomControlsEnabled: false,
            clusterManagers: 
            padding: const EdgeInsets.only(
              top: 180,
            ),
            onCameraMove: _onCameraMove,
            markers: widget.markers,
            buildingsEnabled: false,
            myLocationEnabled: true,
            myLocationButtonEnabled: true,
            onMapCreated: _onMapCreated,
            initialCameraPosition: CameraPosition(
              target: widget.center,
              zoom: widget.zoom,
            ),
            rotateGesturesEnabled: true,
            zoomGesturesEnabled: true,
            scrollGesturesEnabled: true,
            tiltGesturesEnabled: true,
          );
        },
      ),
    );
  }

  void _pageChanged(int index) {
    setState(() => currentIndex = index);
    widget.onLastItem?.call();
    // _zoomToCurrentMarker();
  }

  // void _zoomToCurrentMarker() {
  //   if (mapController == null || widget.markers.isEmpty) return;

  //   final marker = widget.markers[currentIndex];
  //   mapController?.animateCamera(
  //     widget.zoomKeepOnTap
  //         ? CameraUpdate.newLatLng(LatLng(marker.latitude, marker.longitude))
  //         : CameraUpdate.newCameraPosition(
  //             CameraPosition(
  //               target: LatLng(marker.latitude, marker.longitude),
  //               zoom: widget.zoomFocus,
  //             ),
  //           ),
  //   );
  // }
}
Leave a Comment