본문 바로가기

06. 앱

00006. 📌 [APP-00001] 실시간 미세먼지 & 날씨 알림 앱 #5 – 날씨 & 미세먼지 정보를 화면에 예쁘게 보여주기

반응형

안녕하세요! 이번 글은 실시간 미세먼지 & 날씨 알림 앱 개발 시리즈의 다섯 번째 글입니다.
지난 글에서는 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 – 새로고침 기능 & 자동 데이터 갱신 구현하기

그럼 다음 포스팅에서 만나요! ☀️🌫️

반응형