flutter 谷歌Map自定义标记从URL加载缓慢

mkh04yzy  于 2023-03-31  发布在  Flutter
关注(0)|答案(1)|浏览(118)

问题,标记需要大约10秒加载,尽管事实上,他们是非常小的图标。我敢肯定有一个问题,我调用他们加载的方式。我希望他们几乎是即时的。我有一个工作的谷歌Map的例子链接在这里。你会看到标记下载缓慢。我有另一个例子,这在FlutterMap,它工作正常,并立即加载一切。我需要做什么才能让我的标记在GoogleMap上一次加载所有内容?

import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:flutter/material.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';
import 'package:custom_marker/marker_icon.dart';
import '../../models/marker_collect_model.dart';

class PhotoCustomMap extends StatefulWidget {
  @override
  _PhotoCustomMapState createState() => _PhotoCustomMapState();
}

class _PhotoCustomMapState extends State<PhotoCustomMap> {
  List<Marker> list = [];
  List<String> listDocuments = [];

  Future<void> readDataFromFirebase() async {
    await Firebase.initializeApp();
    FirebaseFirestore firestore = FirebaseFirestore.instance;
    CollectionReference<Map<String, dynamic>> collectionReference =
    firestore.collection('NWNSPHOTOS2023');
    collectionReference.snapshots().listen((event) async {
      List<DocumentSnapshot> snapshots = event.docs;
      for (var map in snapshots) {
        Map<String, dynamic> data =
        map.data() as Map<String, dynamic>; // add this line
        MarkerCollectModel model =
        MarkerCollectModel.fromMap(data); // use data here
        String nameDocument = map.id;
        listDocuments.add(nameDocument);
        Marker marker = await createMarker(model, nameDocument);
        setState(() {
          list.add(marker);
        });
      }
    });
  }

  Future<Marker> createMarker(
      MarkerCollectModel markerCollectModel, String nameDocument) async {

    BitmapDescriptor bitmapDescriptor = await MarkerIcon.downloadResizePictureCircle(
        markerCollectModel.pathImageSmall!,
        addBorder: true,
        borderColor: Colors.blue,
        borderSize: 5,
        size: 50
    );

    Marker marker;
    marker = Marker(
      markerId: MarkerId(nameDocument),
      position: LatLng(markerCollectModel.lat!, markerCollectModel.lng!),
      icon: bitmapDescriptor,
    );
    return marker;
  }

  Set<Marker> myMarkers() {
    return list.toSet();
  }

  // Method
  @override
  void initState() {
    super.initState();
    readDataFromFirebase();
  }

  @override
  Widget build(BuildContext context) {
    WidgetsFlutterBinding.ensureInitialized();
    Firebase.initializeApp();
    CameraPosition cameraPosition =
    CameraPosition(target: LatLng(47.088717, -122.496509), zoom: 7.7);
    return Scaffold(
        body: Center(
            child: Stack(
              children: <Widget>[
                GoogleMap(
                  initialCameraPosition: cameraPosition,
                  markers: myMarkers(),
                ),
              ],
            )));
  }
}

最后的工作版本与下面的帮助。

import 'dart:async';
import 'dart:ui';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_cache_manager/flutter_cache_manager.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';
import 'package:rideyrbiketracker/pages/screens/DetailScreen.dart';

import '../../models/marker_collect_model.dart';

class PhotoMap extends StatefulWidget {
  @override
  _PhotoMapState createState() => _PhotoMapState();
}

class _PhotoMapState extends State<PhotoMap> {
  GoogleMapController? controller;
  Set<Polyline> _polylines = {};
  bool imagetapped = false;
  List<Marker> list = [];
  List<String> listDocuments = [];

  Future<void> readDataFromFirebase() async {
    await Firebase.initializeApp();
    FirebaseFirestore firestore = FirebaseFirestore.instance;
    CollectionReference<Map<String, dynamic>> collectionReference =
    firestore.collection('NWNSPHOTOS2023');

    List<Marker> markers = [];
    List<String> documents = [];
    (await collectionReference.get()).docs.forEach((doc) async {
      Map<String, dynamic> data = doc.data();
      MarkerCollectModel model = MarkerCollectModel.fromMap(data);
      String nameDocument = doc.id;

        final markerImageFile = (await DefaultCacheManager()
            .getSingleFile(model.pathImageSmall!));
        final Uint8List bytes = await markerImageFile.readAsBytes();

        final Codec markerImageCodec = await instantiateImageCodec(
            bytes,
            targetHeight: 50,
            targetWidth: 50
        );

        final FrameInfo frameInfo = await markerImageCodec.getNextFrame();

        final ByteData? byteData = await frameInfo.image.toByteData(
          format: ImageByteFormat.png,
        );

        final Uint8List resizedMarkerImageBytes = byteData!.buffer.asUint8List();

        BitmapDescriptor _bitmapDescriptor = BitmapDescriptor.fromBytes(resizedMarkerImageBytes, size: Size(50, 50));

        markers.add(Marker(
          markerId: MarkerId(nameDocument),
          position: LatLng(model.lat!, model.lng!),
          icon: _bitmapDescriptor,
          onTap: () {
            MaterialPageRoute route = MaterialPageRoute(
              builder: (context) => DetailScreener(model),
            );
            Navigator.push(context, route);
          },
          infoWindow: InfoWindow(
            title: model.name! +
                " | | " +
                "MILE: " +
                model.mileager!,
            snippet: '${model.dateTime}',
            onTap: () {
              MaterialPageRoute route = MaterialPageRoute(
                builder: (context) => DetailScreener(model),
              );
              Navigator.push(context, route);
            },
          ),
        ));

        setState(() {
          list = markers;
          listDocuments = documents;
        });
      });
  }

  Set<Marker> myMarkers() {
    return list.toSet();
  }

  // Method
  @override
  void initState() {
    super.initState();

    const oneSec = Duration(seconds:15);
    readDataFromFirebase();
    Timer.periodic(oneSec, (Timer t) =>
        readDataFromFirebase());
  }
  
  @override
  Widget build(BuildContext context) {
    WidgetsFlutterBinding.ensureInitialized();
    Firebase.initializeApp();
    CameraPosition cameraPosition =
        CameraPosition(target: LatLng(47.088717, -122.496509), zoom: 7.7);
    return Scaffold(
        body: Center(
            child: Stack(
      children: <Widget>[
        GoogleMap(
          initialCameraPosition: cameraPosition,
          markers: myMarkers(),
          polylines: _polylines,
        ),
      ],
    )));
  }
}
k10s72fa

k10s72fa1#

我只是更新了你的代码,做了一些修正,

import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:flutter/material.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';
import 'package:custom_marker/marker_icon.dart';
import '../../models/marker_collect_model.dart';

class PhotoCustomMap extends StatefulWidget {
  @override
  _PhotoCustomMapState createState() => _PhotoCustomMapState();
}

class _PhotoCustomMapState extends State<PhotoCustomMap> {
  List<Marker> list = [];
  List<String> listDocuments = [];

  Future<void> readDataFromFirebase() async {
    await Firebase.initializeApp();
    FirebaseFirestore firestore = FirebaseFirestore.instance;
    CollectionReference<Map<String, dynamic>> collectionReference =
        firestore.collection('NWNSPHOTOS2023');
    List<Marker> markers = [];
    List<String> documents = [];
    (await collectionReference.get()).docs.forEach((doc) async {
      Map<String, dynamic> data = doc.data() as Map<String, dynamic>;
      MarkerCollectModel model = MarkerCollectModel.fromMap(data);
      String document = doc.id;
      BitmapDescriptor bitmapDescriptor = await MarkerIcon.downloadResizePictureCircle(
        model.pathImageSmall!,
        addBorder: true,
        borderColor: Colors.blue,
        borderSize: 5,
        size: 50,
      );
      markers.add(Marker(
        markerId: MarkerId(document),
        position: LatLng(model.lat!, model.lng!),
        icon: bitmapDescriptor,
      ));
      documents.add(document);
    });
    setState(() {
      list = markers;
      listDocuments = documents;
    });
  }

  Set<Marker> myMarkers() {
    return list.toSet();
  }

  // Method
  @override
  void initState() {
    super.initState();
    readDataFromFirebase();
  }

  @override
  Widget build(BuildContext context) {
    WidgetsFlutterBinding.ensureInitialized();
    Firebase.initializeApp();
    CameraPosition cameraPosition =
        CameraPosition(target: LatLng(47.088717, -122.496509), zoom: 7.7);
    return Scaffold(
        body: Center(
            child: Stack(
      children: <Widget>[
        GoogleMap(
          initialCameraPosition: cameraPosition,
          markers: myMarkers(),
        ),
      ],
    )));
  }
}

基本上,createMarker()方法被删除,标记被创建并添加到readDataFromFirebase()循环中的列表中。当标记被创建时,list和listDocuments列表在setState()中被设置。myMarkers()方法被更新并返回标记到list。

相关问题