[Flutter]googlemapのサンプルをriverpodで書き換える

この記事にあるサンプルをriverpod、state_notifierを使って書き換える。

元のコードは以下の通り

import 'dart:async';
import 'package:flutter/material.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';

class MapSample extends StatefulWidget {
 @override
 State<MapSample> createState() => MapSampleState();
}
class MapSampleState extends State<MapSample> {
 Completer<GoogleMapController> _controller = Completer();
 static final CameraPosition _kGooglePlex = CameraPosition(
   target: LatLng(37.42796133580664, -122.085749655962),
   zoom: 14.4746,
 );
 static final CameraPosition _kLake = CameraPosition(
     bearing: 192.8334901395799,
     target: LatLng(37.43296265331129, -122.08832357078792),
     tilt: 59.440717697143555,
     zoom: 19.151926040649414);
 @override
 Widget build(BuildContext context) {
   return new Scaffold(
     body: GoogleMap(
       mapType: MapType.hybrid,
       initialCameraPosition: _kGooglePlex,
       onMapCreated: (GoogleMapController controller) {
         _controller.complete(controller);
       },
     ),
     floatingActionButton: FloatingActionButton.extended(
       onPressed: _goToTheLake,
       label: Text('To the lake!'),
       icon: Icon(Icons.directions_boat),
     ),
   );
 }
 Future<void> _goToTheLake() async {
   final GoogleMapController controller = await _controller.future;
   controller.animateCamera(CameraUpdate.newCameraPosition(_kLake));
 }
}

riverpodで書き換えたものは

import 'dart:async';
import 'package:flutter/material.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:flutter/foundation.dart'; // *.freezed.dartで必要なのでimportしておく
import 'package:freezed_annotation/freezed_annotation.dart';

part 'googlemap.freezed.dart';

@freezed
abstract class GoogleMapState with _$GoogleMapState {
 const factory GoogleMapState({
   Completer<GoogleMapController> controller,
 }) = _GoogleMapState;
}

final googleMapStateProvider =
   StateNotifierProvider((_) => GoogleMapStateProvider());

class GoogleMapStateProvider extends StateNotifier<GoogleMapState> {
 GoogleMapStateProvider() : super(const GoogleMapState());
 
 void initState() async {
   state = state.copyWith(controller: Completer());
 }
 
 void dispose() {}
 
 Future<void> goToTheLake(pos) async {
   final GoogleMapController controller = await state.controller.future;
   controller.animateCamera(CameraUpdate.newCameraPosition(pos));
 }
}

class MapSample extends HookWidget {
 
 static final CameraPosition _kGooglePlex = CameraPosition(
   target: LatLng(37.42796133580664, -122.085749655962),
   zoom: 14.4746,
 );
 
 static final CameraPosition _kLake = CameraPosition(
     bearing: 192.8334901395799,
     target: LatLng(37.43296265331129, -122.08832357078792),
     tilt: 59.440717697143555,
     zoom: 19.151926040649414);

 @override
 Widget build(BuildContext context) {
   final gmsp = useProvider(googleMapStateProvider);
   final gmState = useProvider(googleMapStateProvider.state);
   useEffect(() {
     Future.microtask(() => gmsp.initState());
     return () {};
   }, []);
   
   return new Scaffold(
     body: GoogleMap(
       mapType: MapType.hybrid,
       initialCameraPosition: _kGooglePlex,
       onMapCreated: (GoogleMapController controller) {
         gmState.controller.complete(controller);
       },
     ),
     floatingActionButton: FloatingActionButton.extended(
       onPressed: () {
         gmsp.goToTheLake(_kLake);
       },
       label: Text('To the lake!'),
       icon: Icon(Icons.directions_boat),
     ),
   );
 }
}

いいなと思ったら応援しよう!