https://pub.dev/ 에서 필요한 패키지 다운
https://mapsplatform.google.com/ 에서 API키 발급
Get started -> API 및 서비스
(Maps SDK for Android, Maps SDK for iOS 가 활성화되야함
static const LatLng companyLatLag = LatLng(
37.49793912003677,
127.02758462751584,
);
static const CameraPosition initialPosition = CameraPosition(
target: companyLatLag,
zoom: 15, //숫자가 낮을 수록 멀리서 보임
);
Widget build(BuildContext context) {
return const Scaffold(
body: GoogleMap(
mapType: MapType.terrain, //맵 종류 선택
initialCameraPosition: initialPosition,
),
);
}
Future<String> checkPermission() async {
// 로케이션 서비스가 활성화가 돼있는지 확인
final isLocationEnbled = await Geolocator.isLocationServiceEnabled();
if (!isLocationEnbled) {
return '위치 서비스를 활성화 해주세요.';
}
//현재 앱이 갖고 있는 위치서비스에 대한 권한이 어떻게 되는지 가져옴
LocationPermission checkedPermision = await Geolocator.checkPermission();
if (checkedPermision == LocationPermission.denied) {
//denied면 초기상태로 한번은 request해주지만
checkedPermision = await Geolocator.requestPermission();
//그래도 denied면 텍스트 띄움
if (checkedPermision == LocationPermission.denied) {
return '위치권한을 허용해주세요.';
}
}
if (checkedPermision == LocationPermission.deniedForever) {
return '앱의 위치 권한을 세팅에서 허가해주세요.';
}
return '위치권한이 허용되었습니다.';
}
FutureBuilder(future: future, builder: builder)
future를 리턴해주는 어떤 함수든 넣을수 있음 (Future<String> chec~
)
future의 함수의 상태가 변경이 될 때마다 함수의 상태가 로딩중이거나 로딩이끝났거나 어떤 데이터가 리턴됐거나 에러가 터졌거나 등 상황이 됐을 때 builder:(){}를 다시 실행해가지고 화면을 다시 그려줄 수 있다.
future안에 들어간 함수가 리턴해준 값을 snapshot에서 또 받아볼 수 있다.
print(snapshot.data);
- 함수의 return값 print(snapshot.connectionState);
- 함수 현재 상태확인return Scaffold(
appBar: renderAppBar(),
body: FutureBuilder(
future: checkPermission(),
builder: (BuildContext context, AsyncSnapshot snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return const Center(child: CircularProgressIndicator());
}
// data가 '위치권한이 허용되었습니다.'면 지도 리턴해줌
if (snapshot.data == '위치권한이 허용되었습니다.') {
return const Column(
children: [
_CustomGoogleMap(initialPosition: initialPosition),
_ChoolCheckButton(),
],
);
}
return Center(
child: Text(snapshot.data),
);
},
),
);
시뮬레이터(안드로이드) 옆에 ... 누르고 Location에서 폰 위치 설정해줌 (안하면 구글 본사 잡히는것 같다.)
GoogleMap위젯에 myLocationEnabled: true,
속성 추가해주면 현재위치를 표시해주는 원이 그려진다.
child: GoogleMap(
mapType: MapType.normal,
initialCameraPosition: initialPosition,
myLocationEnabled: true,
),
반경 100m 이내에서만 출석할수 있게하기
companyLatLag를 위치로 기준으로 함
Circle 만들어줌
static const double distance = 100;
static Circle circle = Circle(
circleId: const CircleId('circle'), //여러 동그라미 그렸을때 구분하기 위함
center: companyLatLag, //companyLatLag를 위치로 기준
fillColor: Colors.blue.withOpacity(0.5),
radius: distance, //반지름 - 출석체크를 해줄수있는 거리
strokeColor: Colors.blue,
strokeWidth: 1,
);
_CustomGoogleMap
에서 final Circle circle;
받아와서 GoogleMap위젯에 circles: {circle},
를 추가해준다.(Set이라 {}로 감싸줘야함)companyLatLag를 위치로 기준으로 함
Circle 만들어줌
static Marker marker = const Marker(
markerId: MarkerId('marker'),
position: companyLatLag,
);
_CustomGoogleMap
에서 final Marker marker;
받아와서 GoogleMap위젯에 markers: {marker},
를 추가해준다.반경 밖에 있을때 빨강/ 반경 안에 있을 떄 파랑/ 출석체크 했을 때 초록
circle를 세개 만들어서 StreamBuilder<Position>
내 위치를 Position 클래스로 보내준다.
Geolocator.getPositionStream()
메서드는 현재 위치가 변경이될 때마다 값이 Stream에서 리턴(빌드)이 되게 해준다.
start은 내 현재위치/ end는 회사로 위치로 할당해주고
start와 end의 거리를 실시간으로 구해야되기 때문에 Geolocator.distanceBetween()
메서드를 사용한다.
distance는 거리를 구하고, okDistance는 100m라고 설정이 되어있다.
그래서 if (distance < okDistance){isWithinRange = true;}
를 통해 현재 start와 end의 거리가 100m보다 작으면 isWithinRange를 true로 할당해준다.
isWithinRange를 활용해서 _CustomGoogleMap
에 조건문으로 circle를 넘겨주고
_ChoolCheckButton
도 isWithinRange활용해서 조건문으로 버튼색 바꿔주고
[출근하기] 버튼도 조건문으로 보여준다.
if (snapshot.data == '위치권한이 허용되었습니다.') {
return StreamBuilder<Position>(
stream: Geolocator
.getPositionStream(), //현재 위치가 변경이될 때마다 값이 스트림에서 리턴(빌드)이 됨다.
builder: (context, snapshot) {
// print(snapshot.data); //현재위치에따라 실시간으로 빌드되는지 위경도찍어봄
bool isWithinRange = false;
if (snapshot.hasData) {
final start = snapshot
.data!; //내 위치를<Position>이라는 클래스로 표현한게 snapshot.data
const end = companyLatLag;
// 거리를 구하는 함수
final distance = Geolocator.distanceBetween(
start.latitude,
start.longitude,
end.latitude,
end.longitude,
);
if (distance < okDistance) {
isWithinRange = true;
}
}
return Column(
children: [
_CustomGoogleMap(
initialPosition: initialPosition,
circle: isWithinRange
? whitDistanceCircle
: notWhitDistanceCircle,
marker: marker,
),
_ChoolCheckButton(
isWithinRange: isWithinRange,
onPressed: onCoolCheckPressed),
],
);
},
);
}
materialDialog 패키지에서 showDialog(context: context, builder: builder)
가져옴
AlertDialog 위젯을 사용해서 위젯을 띄어줌
actions로 선택할 수 있는 버튼을 추가할 수 있다.
안녕하세요 구글 지도 패키지에 저런 원형 마커가 없던데 어떻게 설정하신건가요? 궁금합니다...