[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),
),
);
}
}