【问题标题】:How to convert GoogleMaps stateful class to stateless class of GetX with GetX controller?如何使用 GetX 控制器将 GoogleMaps 有状态类转换为 GetX 的无状态类?
【发布时间】:2023-01-14 09:24:02
【问题描述】:

我一直在尝试将下面显示的类转换为带有 GetX 控制器的无状态类。我想让一个 GetX 控制器连接到该类并使该类无状态并使所有变量都成为对象。这不是我第一次使用 GetX 构造函数将类转换为无状态,但对于 GoogleMap 我无法做到这一点。

这是我要转换为的类:

import 'dart:async';
import 'dart:convert';
import 'package:get/get.dart';
import 'package:http/http.dart' as http;
import 'package:geolocator/geolocator.dart';
import 'package:flutter/material.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';
import 'package:shared_preferences/shared_preferences.dart';

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

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

class _MapScreenState extends State<MapScreen> {
  bool isLoading = false;
  static const url = 'http://10.0.2.2:8000/api/events';
  static const header = {
    "Content-Type": "application/json",
    "Accept": "application/json"
  };
  Completer<GoogleMapController> completer = Completer();
  late GoogleMapController newGoogleMapController;
  late Position currentPosition;

  Map<MarkerId, Marker> markers = <MarkerId, Marker>{};
  late Position position;

  void getMarkers(double lat, double long) async {
    MarkerId markerId = MarkerId(lat.toString() + long.toString());
    Marker marker = Marker(
        markerId: markerId,
        position: LatLng(lat, long),
        icon: BitmapDescriptor.defaultMarkerWithHue(BitmapDescriptor.hueRed));
    setState(() {
      markers[markerId] = marker;
    });
    var ref = await SharedPreferences.getInstance();
    ref.setDouble("lat", lat);
    ref.setDouble("long", long);
  }

  void getCurrentLocation() async {
    Position currentPosition =
        await GeolocatorPlatform.instance.getCurrentPosition();
    setState(() {
      position = currentPosition;
    });
  }

  @override
  void initState() {
    super.initState();
    getCurrentLocation();
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
        home: Scaffold(
      body: isLoading ? Center(child: CircularProgressIndicator()) : Stack(
        children: [
          GoogleMap(
            mapType: MapType.hybrid,
            initialCameraPosition: CameraPosition(
                target: LatLng(35.14607815137796, 33.90850919853462),
                zoom: 16),
            myLocationEnabled: true,
            zoomGesturesEnabled: true,
            zoomControlsEnabled: false,
            onMapCreated: (GoogleMapController controller) {
              completer.complete(controller);
              newGoogleMapController = controller;
            },
            onTap: (tapped) async {
              var ref = await SharedPreferences.getInstance();
              if (markers.values.isEmpty) {
                getMarkers(tapped.latitude, tapped.longitude);
              } else {
                markers.clear();
                getMarkers(tapped.latitude, tapped.longitude);
              }
              print(ref.getDouble("lat").toString());
              print(ref.getDouble("long").toString());
            },
            markers: Set<Marker>.of(markers.values),

          ),
          Align(
              alignment: Alignment.bottomCenter,
              child: ElevatedButton(onPressed: () async {
                submitEvent();
                }, child: Text('Submit'), style: ElevatedButton.styleFrom(
                  fixedSize: Size(200, 40),
                  primary: Color(0xff1b5a9d),
                  elevation: 2
              ),)),
        ],
      ),
    ));
  }

  Future submitEvent() async {
    setState(() {
      isLoading=true;
    });
    var ref = await SharedPreferences.getInstance();
    final data = {
      "user_id": ref.getInt("userID"),
      "staff_id": null,
      "document_id": ref.getInt("documentId"),
      "event_status_id": 3,
      "event_type_id": int.parse(ref.getString("eventTypeId").toString()),
      "lat": ref.getDouble("lat"),
      "lon": ref.getDouble("long"),
      "description": ref.getString("description"),
      "note": 'Note',
    };
    return http.post(Uri.parse(url), headers: header, body: jsonEncode(data)).then((value) {
      if(value.statusCode == 200 && value.body.isNotEmpty){
        Get.snackbar("Success", "Successfully Updated",
            colorText: Colors.white,
            icon: Icon(Icons.check_circle, color: Colors.white),
            snackPosition: SnackPosition.TOP,
            backgroundColor: Colors.green);
        setState(() {
          isLoading=false;
        });
      }
      else {
        setState(() {
          isLoading=false;
        });
        Get.snackbar("Error", "An error has occured",
            colorText: Colors.white,
            icon: Icon(Icons.error, color: Colors.white),
            snackPosition: SnackPosition.TOP,
            backgroundColor: Color(0xffeb3030));
      }
    });
  }
}

【问题讨论】:

  • 你可以检查我前段时间做的一个项目,我必须更新到谷歌地图,你可以检查主要的“master”和分支“migration_to_map”,这是回购:github.com/WilliBobadilla/wakeApp2.0

标签: flutter google-maps flutter-getx


【解决方案1】:

检查下面的代码,imo 最好使用 flutter_easyloading 而不是 isLoading 布尔值,在这种情况下,您可以删除 GetBuilder 并通过 Get.find() 获取控制器实例或使用 GetView 而不是 StatelessWidget

地图屏幕视图

class MapScreenView extends StatelessWidget {
  const MapScreenView({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return GetBuilder<MapScreenController>(
      builder: (controller) {
        return Scaffold(
          body: controller.isLoading
              ? const Center(child: CircularProgressIndicator())
              : Stack(
                  children: [
                    GoogleMap(
                      mapType: MapType.hybrid,
                      initialCameraPosition: controller.kCameraPosition,
                      myLocationEnabled: true,
                      zoomGesturesEnabled: true,
                      zoomControlsEnabled: false,
                      onMapCreated: (GoogleMapController ctrl) {
                        controller.completer.complete(ctrl);
                      },
                      onTap: controller.onMapTapped,
                      markers: Set<Marker>.of(controller.markers.values),
                    ),
                    Align(
                        alignment: Alignment.bottomCenter,
                        child: ElevatedButton(
                          onPressed: () async => await controller.submitEvent(),
                          style: ElevatedButton.styleFrom(
                              fixedSize: const Size(200, 40), backgroundColor: const Color(0xff1b5a9d), elevation: 2),
                          child: const Text('Submit'),
                        )),
                  ],
                ),
        );
      },
    );
  }
}

地图屏幕控制器

class MapScreenController extends GetxController {
  bool isLoading = false;
  static const url = 'http://10.0.2.2:8000/api/events';
  static const header = {"Content-Type": "application/json", "Accept": "application/json"};
  Completer<GoogleMapController> completer = Completer();
  late Position currentPosition;
  CameraPosition kCameraPosition = const CameraPosition(target: LatLng(35.14607815137796, 33.90850919853462), zoom: 16);
  Map<MarkerId, Marker> markers = <MarkerId, Marker>{};
  late Position position;

  void getMarkers(double lat, double long) async {
    MarkerId markerId = MarkerId(lat.toString() + long.toString());
    Marker marker = Marker(
        markerId: markerId,
        position: LatLng(lat, long),
        icon: BitmapDescriptor.defaultMarkerWithHue(BitmapDescriptor.hueRed));
    markers[markerId] = marker;
    var ref = await SharedPreferences.getInstance();
    ref.setDouble("lat", lat);
    ref.setDouble("long", long);
  }

  void getCurrentLocation() async {
    Position currentPosition = await GeolocatorPlatform.instance.getCurrentPosition();
    position = currentPosition;
  }

  void onMapTapped(LatLng latLng) {
    if (markers.values.isEmpty) {
      getMarkers(latLng.latitude, latLng.longitude);
    } else {
      markers.clear();
      getMarkers(latLng.latitude, latLng.longitude);
    }
  }

  Future<void> submitEvent() async {
    isLoading = true;
    update();
    var ref = await SharedPreferences.getInstance();
    final data = {
      "user_id": ref.getInt("userID"),
      "staff_id": null,
      "document_id": ref.getInt("documentId"),
      "event_status_id": 3,
      "event_type_id": int.parse(ref.getString("eventTypeId").toString()),
      "lat": ref.getDouble("lat"),
      "lon": ref.getDouble("long"),
      "description": ref.getString("description"),
      "note": 'Note',
    };

    await http.post(Uri.parse(url), headers: header, body: jsonEncode(data)).then((value) {
      if (value.statusCode == 200 && value.body.isNotEmpty) {
        Get.snackbar("Success", "Successfully Updated",
            colorText: Colors.white,
            icon: const Icon(Icons.check_circle, color: Colors.white),
            snackPosition: SnackPosition.TOP,
            backgroundColor: Colors.green);
        isLoading = false;
        update();
      } else {
        isLoading = false;
        update();
        Get.snackbar("Error", "An error has occurred",
            colorText: Colors.white,
            icon: const Icon(Icons.error, color: Colors.white),
            snackPosition: SnackPosition.TOP,
            backgroundColor: const Color(0xffeb3030));
      }
    });
  }
}

【讨论】:

    猜你喜欢
    • 2020-11-26
    • 2022-01-21
    • 2021-08-20
    • 2021-11-06
    • 2021-11-08
    • 2021-12-10
    • 2021-11-19
    • 1970-01-01
    • 2021-11-01
    相关资源
    最近更新 更多