구글 맵을 펼칠 때 처음 현재위치 마커와 아이콘 클릭 시 현재 위치로 이동하여 마커를 찍어주는 기능을 만든다.
처음 카메라위치와 마커를 initState() 부분에 만들어준다. 마커는 리스트에 담아서 관리한다.
안드로이드 에뮬리이터에서 위치를 받는데 무조건 구글로 위치가 뜬다..
그래서 처음 위치는 조금 옆의 호수로 정하고, 아이콘 클릭 시 현재위치를 구글로 보내준다..
여기서 지도 타입만 변경해주는 버튼을 만들어서 선택할 때마다 지도 타입을 변화시켜준다.
gps 아이콘 버튼을 하단에 생성해주고 클릭 시 현재 위치로 이동하면서 마커를 찍어준다.
import 'dart:async';
import 'dart:developer';
import 'package:flutter/material.dart';
import 'package:flutter_map/map_provider.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';
import 'package:provider/provider.dart';
class MapSample extends StatefulWidget {
const MapSample({Key? key}) : super(key: key);
@override
State<MapSample> createState() => MapSampleState();
}
class MapSampleState extends State<MapSample> {
late GoogleMapController _mapController;
CameraPosition? initialCameraPosition;
Marker? initialPositionMarker;
List<Marker> markers = [];
@override
void initState() {
super.initState();
setState(() {
initialCameraPosition = const CameraPosition(
target: LatLng(37.43263980495858, -122.09192861197333),
zoom: 14.4746,
);
initialPositionMarker = const Marker(
markerId: MarkerId("initial"),
position: LatLng(37.43263980495858, -122.09192861197333),
);
markers.add(initialPositionMarker!);
});
// context.read<MapProvider>().getInitialPosition().then((value) {
// initialCameraPosition = CameraPosition(
// target: LatLng(value.latitude, value.longitude),
// zoom: 14.4746,
// );
// initialPositionMarker = Marker(
// markerId: MarkerId("current"),
// position: LatLng(value.latitude, value.longitude),
// );
// log("initial position : $value");
// });
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Consumer<MapProvider>(
builder: (BuildContext context, _, Widget? child) {
return Stack(
children: [
GoogleMap(
mapType: _.mapType,
initialCameraPosition: initialCameraPosition!,
onMapCreated: (GoogleMapController controller) {
setState(() {
_mapController = controller;
});
},
markers: Set.from(markers)
),
Positioned(
top: 30,
right: 10,
child: ElevatedButton(
onPressed: () {
_.setMapType();
},
style: ElevatedButton.styleFrom(
backgroundColor: Colors.amber, // 주색상
fixedSize: Size(50, 30),
),
child: Text(_.mapTypeText),
)
),
Positioned(
bottom: 30,
left: 10,
child: FloatingActionButton(
onPressed: () async {
await _.getCurrentPosition().then((value) {
_mapController.animateCamera(
CameraUpdate.newCameraPosition(
CameraPosition(
target: LatLng(value.latitude, value.longitude),
zoom: 15
)
)
);
Marker currentPositionMarker = Marker(
markerId: const MarkerId("current"),
position: LatLng(value.latitude, value.longitude),
);
_.addMarker(markers, currentPositionMarker);
});
},
backgroundColor: Colors.white,
child: const Icon(Icons.gps_fixed, color: Colors.black, size: 30),
),
),
],
);
},
),
);
}
}
import 'dart:developer';
import 'package:flutter/material.dart';
import 'package:geolocator/geolocator.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';
class MapProvider extends ChangeNotifier {
MapType mapType = MapType.hybrid;
String mapTypeText = "위성";
int mapTypeIndex = 0;
/// 현재 위치 조회
Future<Position> getCurrentPosition() async {
log("getCurrentPosition");
return await Geolocator.getCurrentPosition();
}
/// 초기 위치 조회
Future<Position> getInitialPosition() async {
log("getInitialPosition");
bool serviceEnabled;
serviceEnabled = await Geolocator.isLocationServiceEnabled();
if (!serviceEnabled) {
return Future.error('Location services are disabled.');
}
return await Geolocator.getCurrentPosition();
}
void addMarker(List<Marker> markers, Marker addMarker) {
markers.add(addMarker);
notifyListeners();
}
/// 지도 타입 변경
void setMapType() {
if (mapTypeIndex < 2) {
mapTypeIndex ++;
} else {
mapTypeIndex = 0;
}
switch (mapTypeIndex) {
case 0:
mapType = MapType.normal;
mapTypeText = "기본";
break;
case 1:
mapType = MapType.terrain;
mapTypeText = "고도";
break;
case 2:
mapType = MapType.hybrid;
mapTypeText = "위성";
break;
}
notifyListeners();
}
}
'dev > flutter' 카테고리의 다른 글
GetX 컨트롤러 tag (0) | 2023.04.05 |
---|---|
파일 다운로드 (0) | 2023.03.22 |
provider (0) | 2023.01.29 |
[map_app] google map (IOS, 안드로이드) (0) | 2023.01.27 |
statusbar 뒤에 이미지 넣기 (0) | 2023.01.25 |