목표
10초마다 위치 정보를 받아오는 provider를 만들고, 위치 정보가 바뀌면 특정 화면 UI에 경도와 위도 값을 표시해주고 싶음
Riverpod
Flutter/Dart를 위한 반응형 캐싱 프레임워크(Reactive caching framework)로 getX, provider 등과 같은 플러터의 상태 관리 패키지 중 하나
프로젝트 세팅
라이브러리 세팅 pubspec.yaml
1
2
3
| dependencies:
flutter_riverpod: ^2.5.1
geolocator: ^12.0.0
|
riverpod 세팅
- riverpod provider을 사용하기 위해서는 앱의 루트를
ProviderScope
로 감싸주어야 함
1
2
3
4
| void main() {
WidgetsFlutterBinding.ensureInitialized();
runApp(const ProviderScope(child: MyApp()));
}
|
- 화면을
ConsumerStatefulWidget
으로 감싸면 provider를 참조할 수 있도록 하는 ref
객체를 사용할 수 있게 됨
1
2
3
4
5
6
7
8
9
10
11
12
13
| class LocationInfoPage extends ConsumerStatefulWidget {
const LocationInfoPage({super.key});
@override
ConsumerState<ConsumerStatefulWidget> createState() => LocationInfoState();
}
class LocationInfoState extends ConsumerState<LocationInfoPage> {
@override
Widget build(BuildContext context) {
// 코드 작성...
}
}
|
provider 생성 location_provider.dart
- locationProvider를 전역으로 생성해 어디서든지 해당 provider를 참조할 수 있도록 함
1
2
3
| final locationProvider = ChangeNotifierProvider<LocationProvider>((ref) {
return LocationProvider();
});
|
전체 코드
main.dart
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
| void main() {
WidgetsFlutterBinding.ensureInitialized();
runApp(const ProviderScope(child: MyApp()));
}
class MyApp extends ConsumerStatefulWidget {
const MyApp({super.key});
@override
ConsumerState<MyApp> createState() => _MyAppState();
}
class _MyAppState extends ConsumerState<MyApp> {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Location updated?',
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
useMaterial3: true,
),
home: const LocationInfoPage(),
);
}
}
|
location_provider.dart
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
| class LocationData {
final double latitude;
final double longitude;
LocationData({required this.latitude, required this.longitude});
}
final locationProvider = ChangeNotifierProvider<LocationProvider>((ref) {
return LocationProvider();
});
class LocationProvider extends ChangeNotifier {
LocationData? _currentLocation;
LocationData? get currentLocation => _currentLocation;
late Timer locationTimer;
// 위치 업데이트 메서드
Future<void> updateLocation() async {
try {
// 10초마다 위치 업데이트
locationTimer =
Timer.periodic(const Duration(seconds: 10), (timer) async {
debugPrint("==== locationProvider... updateLocation ====");
Position position = await Geolocator.getCurrentPosition();
_currentLocation = LocationData(
latitude: position.latitude, longitude: position.longitude);
notifyListeners(); // Provider에게 상태 변경을 알림
});
} catch (e) {
debugPrint('Error updating location: $e');
}
}
@override
void dispose() {
super.dispose();
locationTimer.cancel();
}
}
|
location_info.dart
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
| class LocationInfoPage extends ConsumerStatefulWidget {
const LocationInfoPage({super.key});
@override
ConsumerState<ConsumerStatefulWidget> createState() => LocationInfoState();
}
class LocationInfoState extends ConsumerState<LocationInfoPage> {
@override
void initState() {
super.initState();
requestLocationPermission();
}
// 위치 권한 받아오기
Future<void> requestLocationPermission() async {
LocationPermission permission;
permission = await Geolocator.checkPermission();
if (permission == LocationPermission.denied) {
permission = await Geolocator.requestPermission();
if (permission == LocationPermission.denied) {
debugPrint("location permission is denied.");
return;
} else {
ref.read(locationProvider).updateLocation();
}
} else {
ref.read(locationProvider).updateLocation();
}
}
@override
Widget build(BuildContext context) {
final locationData = ref.watch(locationProvider); // provider의 값을 얻어 변화를 모니터링
return Scaffold(
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
"🏃♀️ latitude: ${locationData.currentLocation?.latitude ?? ''}"),
Text(
"🏃♀️ longitude: ${locationData.currentLocation?.longitude ?? ''}"),
],
),
),
);
}
}
|
결과물
Leave a comment