반응형
안녕하세요! 이번 글은 실시간 미세먼지 & 날씨 알림 앱 개발 시리즈의 다섯 번째 글입니다.
지난 글에서는 OpenWeatherMap과 AirKorea API를 연동하여, 실제 데이터를 받아오는 것까지 완료했죠.
이제 본격적으로 받아온 데이터를 UI에 표시하는 작업을 해보겠습니다.
🎯 목표
- FutureBuilder를 이용해 비동기 데이터 표시
- Card와 Text 위젯을 이용한 시각적 표현
- 미세먼지 수치에 따라 상태(좋음/보통/나쁨) 색상 다르게 표현
📦 1. 데이터 모델 정의하기 (Weather & Dust)
먼저 날씨와 미세먼지 정보를 구조화할 모델 클래스를 간단히 만들어봅니다.
class WeatherInfo {
final String description;
final double temperature;
WeatherInfo({required this.description, required this.temperature});
}
class DustInfo {
final int pm10;
final int pm25;
DustInfo({required this.pm10, required this.pm25});
}
📡 2. 데이터를 받아오는 함수
지난 글에서 만든 API 요청 함수들을 리팩토링하여 다음과 같이 정의합니다:
Future<WeatherInfo> getWeather() async {
// 생략: OpenWeatherMap에서 데이터 요청 후 파싱
return WeatherInfo(description: '맑음', temperature: 17.3);
}
Future<DustInfo> getDust() async {
// 생략: AirKorea에서 데이터 요청 후 파싱
return DustInfo(pm10: 41, pm25: 29);
}
🖼️ 3. UI에 표시하기 – FutureBuilder 활용
데이터를 받아와 UI에 표시하기 위해 FutureBuilder를 활용합니다.
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('실시간 미세먼지 & 날씨')),
body: FutureBuilder(
future: Future.wait([getWeather(), getDust()]),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return Center(child: CircularProgressIndicator());
}
if (snapshot.hasError) {
return Center(child: Text('데이터를 불러오는 데 실패했습니다.'));
}
final weather = snapshot.data![0] as WeatherInfo;
final dust = snapshot.data![1] as DustInfo;
return Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('🌤️ 날씨: ${weather.description}, ${weather.temperature}°C', style: TextStyle(fontSize: 18)),
SizedBox(height: 16),
_buildDustCard('미세먼지(PM10)', dust.pm10),
SizedBox(height: 8),
_buildDustCard('초미세먼지(PM2.5)', dust.pm25),
],
),
);
},
),
);
}
🎨 4. 미세먼지 등급에 따른 색상 처리
미세먼지 수치에 따라 등급을 나누고, 색상도 다르게 표시해봅시다.
Widget _buildDustCard(String label, int value) {
Color bgColor;
String status;
if (value <= 30) {
bgColor = Colors.green;
status = '좋음';
} else if (value <= 80) {
bgColor = Colors.orange;
status = '보통';
} else {
bgColor = Colors.red;
status = '나쁨';
}
return Card(
color: bgColor,
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Text('$label: $value㎍/㎥ ($status)',
style: TextStyle(fontSize: 16, color: Colors.white)),
),
);
}
✅ 마무리
지금까지 받아온 날씨와 미세먼지 데이터를 UI에 시각적으로 표현해보았습니다.
이제 사용자가 앱을 열었을 때 직관적으로 정보를 확인할 수 있게 되었어요.
다음 글에서는 이 데이터를 자동으로 주기적으로 갱신하거나,
사용자가 새로고침 버튼을 눌러 갱신할 수 있는 기능을 추가해볼 예정입니다!
📌 다음 예고
[APP-00001] #6 – 새로고침 기능 & 자동 데이터 갱신 구현하기
그럼 다음 포스팅에서 만나요! ☀️🌫️
반응형