Flutter:如何显示标记之间的折线?

hyrbngr7  于 2023-06-24  发布在  Flutter
关注(0)|答案(2)|浏览(129)

我对谷歌Map这种东西很模糊。虽然标记在Map上可用,但折线不会出现在屏幕上,我似乎无法在Widget构建之外放置标记。

class _MapScreenState extends State<MapScreen> {
  late GoogleMapController mapController;

  LatLng? currentLocation;
  double? currentlat;  double? currentlong;
  LatLng destination = const LatLng(4.66968, 101.07338);
  bool _isLoading = true;
  Set<Marker> markers = {};
  PolylinePoints polylinePoints = PolylinePoints();
  Map<PolylineId, Polyline> polylines = {};
  List<LatLng> polylineCoordinates = [];

  @override
  void initState() {
    super.initState();
    getLocation();
    makeLines();
    addPolyLine();
  }

  getLocation() async {
    Position position = await Geolocator.getCurrentPosition(
        desiredAccuracy: LocationAccuracy.high);
    double lat = position.latitude;
    double long = position.longitude;

    LatLng location = LatLng(lat, long);
    currentlat = lat;
    currentlong = long;

    setState(() {
      currentLocation = location;
      _isLoading = false;
    });
    print("Current Lat: $lat, Long: $long");
  }

  addPolyLine() {
    PolylineId id = const PolylineId("poly");
    Polyline polyline = Polyline(
      polylineId: id,
      color: Colors.blue,
      points: polylineCoordinates,
      width: 3,
    );
    polylines[id] = polyline;
  }

  void makeLines() async {
    await polylinePoints
        .getRouteBetweenCoordinates(
      'API KEY',
      PointLatLng(currentlat??0, currentlong??0),
      PointLatLng(destination.latitude, destination.longitude), //End LATLANG
      travelMode: TravelMode.transit,
    )
        .then((value) {
      value.points.forEach((PointLatLng point) {
        polylineCoordinates.add(LatLng(point.latitude, point.longitude));
      });
    }).then((value) {
      addPolyLine();
    });
  }

  void _onMapCreated(GoogleMapController controller) {
    mapController = controller;
  }
  

  @override
  Widget build(BuildContext context) {
    Marker destinationMarker = Marker(
      markerId: const MarkerId('targetLocation'),
      position: destination,
      infoWindow: const InfoWindow(title: 'Destination'),
    );

      
    Marker currentLocationMarker = Marker(
      icon: BitmapDescriptor.defaultMarkerWithHue(BitmapDescriptor.hueBlue),
      markerId: const MarkerId('currentLocation'),
      position: LatLng(currentlat??0, currentlong??0),
      infoWindow: const InfoWindow(title: 'Current Location'),
    );

    return Scaffold(
      appBar: AppBar(
        title: const Text('Map'),
      ),
      body: _isLoading
          ? const Center(child: CircularProgressIndicator())
          : Center(
            child: Column(
              children: [
                Expanded(
                  child: GoogleMap(
              myLocationEnabled: true,
              onMapCreated: _onMapCreated,
              markers: <Marker>{destinationMarker, currentLocationMarker},
              polylines: Set<Polyline>.of(polylines.values),
              initialCameraPosition: CameraPosition(
                target: currentLocation!,
                zoom: 16.0,
              ),
            ),
                )
              ],
            ),
          )
    );
  }
}

电流输出:https://i.stack.imgur.com/YYaJb.jpg
由于包含我的当前位置,位置的名称被隐藏。
如何将标记放置在小部件构建之外,然后使标记之间的折线可用?

zyfwsgd6

zyfwsgd61#

去Flutter校园看看有你想要的东西

5ktev3wc

5ktev3wc2#

发生问题的原因是贴图在屏幕上渲染,但仍未生成多段线。
你需要使用腕尺,它管理所有这些异步间隙,以获取当前位置并查找polyLines。
你可以参考下面的代码:
MapsCubit.dart:

import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_polyline_points/flutter_polyline_points.dart';
import 'package:geolocator/geolocator.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';

part 'maps_state.dart';

class MapsCubit extends Cubit<MapsState> {
  MapsCubit() : super(MapsInitial());

  Future<void> getCurrentLocation() async {
    emit(MapsLoadingState());

    try {
      Position position = await Geolocator.getCurrentPosition(
          desiredAccuracy: LocationAccuracy.high);
      double lat = position.latitude;
      double long = position.longitude;

      LatLng location = LatLng(lat, long);

      emit(ObtainedCurrentLocation(location: location));
    } catch (e) {
      emit(MapsErrorState(
          errorMessage: 'Error while fetching the current location.'));
    }
  }

  Future<void> getPolyLines(LatLng currentLocation, LatLng destination) async {
    emit(MapsLoadingState());
    try {
      List<LatLng> latLngList = [];

      PolylinePoints points = PolylinePoints();

      PolylineResult polylineResult = await points.getRouteBetweenCoordinates(
        'API KEY',
        PointLatLng(currentLocation.latitude, currentLocation.latitude ?? 0),
        PointLatLng(destination.latitude, destination.longitude),
        travelMode: TravelMode.transit,
      );

      polylineResult.points.forEach((ele) {
        latLngList.add(LatLng(ele.latitude, ele.longitude));
      });

      List<Polyline> polyLines = [];
      polyLines.add(Polyline(
          polylineId: const PolylineId('PolylineId'), points: latLngList));

      emit(ObtainedPolyLines(polyLines: polyLines));
    } catch (e) {
      emit(MapsErrorState(errorMessage: 'Error while finding route'));
    }
  }
}

MapsSate.dart:

part of 'maps_issue_cubit.dart';

abstract class MapsState {}

class MapsInitial extends MapsState {}

class MapsLoadingState extends MapsState {}

class ObtainedCurrentLocation extends MapsState{
  LatLng location;

  ObtainedCurrentLocation({required this.location});
}

class ObtainedPolyLines extends MapsState {
  List<Polyline> polyLines;

  ObtainedPolyLines({required this.polyLines});
}

class MapsErrorState extends MapsState {
  String errorMessage;

  MapsErrorState({required this.errorMessage});
}

和Maps.dart:

import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';
import 'package:mobile_delivery_v2/maps_issue/maps_issue_cubit.dart';

class Maps extends StatefulWidget {
  const Maps({super.key});

  @override
  State<Maps> createState() => _MapsState();
}

class _MapsState extends State<Maps> {
  late MapsCubit cubit;

  late GoogleMapController mapController;
  late LatLng destination;
  late LatLng currentLocation;
  Set<Marker> markers = {};

  @override
  void initState() {
    super.initState();
    destination = const LatLng(4.66968, 101.07338);
    currentLocation = const LatLng(0, 0);
    cubit = MapsCubit();
    cubit.getCurrentLocation();
  }

  void _onMapCreated(GoogleMapController controller) {
    mapController = controller;
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: const Text('Map'),
        ),
        body: BlocConsumer(
          bloc: cubit,
          listener: (context, state) {
            if (state is ObtainedCurrentLocation) {
              currentLocation = state.location;
              cubit.getPolyLines(
                  currentLocation, destination);
              markers.addAll([
                Marker(
                  markerId: const MarkerId('1'),
                  position: currentLocation,
                ),
                Marker(markerId: const MarkerId('2'), position: destination)
              ]);
            }
          },
          builder: (context, state) {
            if (state is ObtainedPolyLines) {
              return GoogleMap(
                myLocationEnabled: true,
                onMapCreated: _onMapCreated,
                markers: markers,
                polylines: Set<Polyline>.of(state.polyLines),
                initialCameraPosition: CameraPosition(
                  target: currentLocation,
                  zoom: 16.0,
                ),
              );
            } else if (state is MapsLoadingState) {
              return const Center(
                child: CircularProgressIndicator(),
              );
            } else if (state is MapsErrorState) {
              return Center(
                child: Text(state.errorMessage),
              );
            }
            return const SizedBox.shrink();
          },
        ));
  }
}

现在,cubit方法getCurrentLocation和getPolyLines将分别管理获取当前位置和生成polyLines的异步操作,并将发出一个状态,而block consumer将捕获它并显示谷歌Map。

相关问题