작성
·
507
답변 4
0
0
import 'package:flutter/material.dart';
import 'package:geolocator/geolocator.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';
class HomeScreen extends StatefulWidget {
const HomeScreen({super.key});
@override
State<HomeScreen> createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen> {
bool choolCheckDone = false;
GoogleMapController? mapController;
static final LatLng companyLatLng = LatLng(35.785756, 128.634620);
static final CameraPosition initialPosition = CameraPosition(
target: companyLatLng,
zoom: 15,
);
static final double okDistance = 100;
static final Circle withinDistanceCircle = Circle(
circleId: CircleId('withinDistanceCircle'),
center: companyLatLng,
fillColor: Colors.blue.withOpacity(0.5),
radius: okDistance,
strokeColor: Colors.blue,
strokeWidth: 1,
);
static final Circle notWithinDistanceCircle = Circle(
circleId: CircleId('notWithinDistanceCircle'),
center: companyLatLng,
fillColor: Colors.red.withOpacity(0.5),
radius: okDistance,
strokeColor: Colors.red,
strokeWidth: 1,
);
static final Circle checkDoneCircle = Circle(
circleId: CircleId('checkDoneCircle'),
center: companyLatLng,
fillColor: Colors.green.withOpacity(0.5),
radius: okDistance,
strokeColor: Colors.green,
strokeWidth: 1,
);
static final Marker marker = Marker(
markerId: MarkerId('marker'),
position: companyLatLng,
);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: renderAppBar(),
body: FutureBuilder(
future: checkPermission(),
builder: (BuildContext context, AsyncSnapshot snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return Center(
child: CircularProgressIndicator(),
);
}
if (snapshot.data == '위치 권한이 허가되었습니다.') {
return StreamBuilder<Position>(
stream: Geolocator.getPositionStream(),
builder: (context, snapshot) {
bool isWithinRange = false;
print(snapshot.hasData);
if (snapshot.hasData) {
final start = snapshot.data!;
final end = companyLatLng;
final distance = Geolocator.distanceBetween(
start.latitude,
start.longitude,
end.latitude,
end.longitude,
);
if (distance < okDistance) {
isWithinRange = true;
}
}
return Column(
children: [
_CustomGoogleMap(
initialPosition: initialPosition,
circle: choolCheckDone
? checkDoneCircle
: isWithinRange
? withinDistanceCircle
: notWithinDistanceCircle,
marker: marker,
onMapCreated: onMapCreated,
),
_CheckButton(
isWithinRange: isWithinRange,
choolCheckDone: choolCheckDone,
onPressed: onCheckPressed,
),
],
);
});
}
return Center(
child: Text(snapshot.data),
);
},
),
);
}
onMapCreated(GoogleMapController controller) {
mapController = controller;
}
onCheckPressed() async {
final result = await showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: Text('출근하기'),
content: Text('출근을 하시겠습니까?'),
actions: [
TextButton(
onPressed: () {
Navigator.of(context).pop(false);
},
child: Text('취소'),
),
TextButton(
onPressed: () {
Navigator.of(context).pop(true);
},
child: Text('출근하기'),
),
],
);
},
);
if (result) {
setState(() {
choolCheckDone = true;
});
}
}
}
Future<String> checkPermission() async {
final isLocationEnabled = await Geolocator.isLocationServiceEnabled();
if (!isLocationEnabled) {
return '위치 서비스를 활성화 해주세요.';
}
LocationPermission checkedPermission = await Geolocator.checkPermission();
if (checkedPermission == LocationPermission.denied) {
checkedPermission = await Geolocator.requestPermission();
if (checkedPermission == LocationPermission.denied) {
return '위치 권한을 허가해주세요.';
}
}
if (checkedPermission == LocationPermission.deniedForever) {
return '앱의 위치 권한을 세팅에서 허가해주세요.';
}
return '위치 권한이 허가되었습니다.';
}
AppBar renderAppBar() {
return AppBar(
centerTitle: true,
title: Text(
'성 주 참 외',
style: TextStyle(
color: Colors.grey[800],
fontWeight: FontWeight.w700,
),
),
backgroundColor: Colors.white,
);
}
class _CustomGoogleMap extends StatelessWidget {
final CameraPosition initialPosition;
final Circle circle;
final Marker marker;
final MapCreatedCallback onMapCreated;
const _CustomGoogleMap({
required this.initialPosition,
required this.circle,
required this.marker,
required this.onMapCreated,
super.key,
});
@override
Widget build(BuildContext context) {
return Expanded(
flex: 3,
child: GoogleMap(
initialCameraPosition: initialPosition,
mapType: MapType.normal,
myLocationEnabled: true,
myLocationButtonEnabled: true,
circles: Set.from([circle]),
markers: Set.from([marker]),
onMapCreated: onMapCreated,
),
);
}
}
class _CheckButton extends StatelessWidget {
final bool isWithinRange;
final VoidCallback onPressed;
final bool choolCheckDone;
const _CheckButton(
{required this.isWithinRange,
required this.onPressed,
required this.choolCheckDone,
super.key});
@override
Widget build(BuildContext context) {
return Expanded(
flex: 1,
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(
Icons.timelapse_outlined,
size: 50.0,
color: choolCheckDone
? Colors.green
: isWithinRange
? Colors.blue
: Colors.red,
),
SizedBox(
height: 20,
),
if (!choolCheckDone && isWithinRange)
TextButton(
onPressed: onPressed,
child: Text(
'출근하기',
style: TextStyle(
color: Colors.grey[800],
),
),
),
],
),
),
);
}
}
0
mapController 변수는 HomeScreenState안에 정의돼있습니다. 그렇기때문에 mapController를 사용하려면 해당 변수를 접근하려는 함수들은 모두 HomeScreenState 안에 선언돼야해요. 이 힌트로 한번 더 파악해보세요