creta_world_weather_api 0.1.0
creta_world_weather_api: ^0.1.0 copied to clipboard
Weather API library for Creta widgets using met.no data with global city coverage.
example/main.dart
import 'package:flutter/material.dart';
import 'package:creta_world_weather_api/creta_world_weather_api.dart';
void main() {
runApp(const CretaWeatherApp());
}
class CretaWeatherApp extends StatefulWidget {
const CretaWeatherApp({super.key});
@override
State<CretaWeatherApp> createState() => _CretaWeatherAppState();
}
class _CretaWeatherAppState extends State<CretaWeatherApp> {
final api = CretaWorldWeatherAPI.instance;
String? selectedNation;
String? selectedCity;
WeatherNow? weather;
bool loading = false;
String? error;
@override
Widget build(BuildContext context) {
final nations = api.getNationCodes();
final cities = selectedNation != null ? api.getCityCodes(selectedNation!) : <String>[];
return MaterialApp(
title: 'Creta Weather Demo',
home: Scaffold(
appBar: AppBar(
title: const Text('Creta World Weather API Demo'),
),
body: Padding(
padding: const EdgeInsets.all(16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
DropdownButtonFormField<String>(
value: selectedNation,
decoration: const InputDecoration(labelText: '국가 선택'),
items: nations.entries
.map((entry) => DropdownMenuItem(
value: entry.key,
child: Text('${entry.value} (${entry.key})'),
))
.toList(),
onChanged: (value) {
setState(() {
selectedNation = value;
selectedCity = null;
weather = null;
});
},
),
const SizedBox(height: 16),
DropdownButtonFormField<String>(
value: selectedCity,
decoration: const InputDecoration(labelText: '도시 선택'),
items: cities
.map((city) => DropdownMenuItem(
value: city,
child: Text(city),
))
.toList(),
onChanged: (value) {
setState(() {
selectedCity = value;
weather = null;
});
},
),
const SizedBox(height: 24),
ElevatedButton(
onPressed: selectedNation != null && selectedCity != null && !loading
? _loadWeather
: null,
child: loading ? const CircularProgressIndicator() : const Text('현재 날씨 가져오기'),
),
const SizedBox(height: 24),
if (error != null)
Text(
error!,
style: const TextStyle(color: Colors.red),
),
if (weather != null) _WeatherCard(weather: weather!),
],
),
),
),
);
}
Future<void> _loadWeather() async {
setState(() {
loading = true;
error = null;
});
try {
final result = await api.getWeatherNow(city: selectedCity!, nationCode: selectedNation!);
setState(() {
weather = result;
});
} catch (e) {
setState(() {
error = '날씨 정보를 가져오지 못했습니다: $e';
});
} finally {
setState(() {
loading = false;
});
}
}
}
class _WeatherCard extends StatelessWidget {
const _WeatherCard({required this.weather});
final WeatherNow weather;
@override
Widget build(BuildContext context) {
return Card(
child: Padding(
padding: const EdgeInsets.all(16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('날씨 유형: ${weather.weatherType}'),
Text('온도: ${weather.temperature.toStringAsFixed(1)}℃'),
Text('강수량: ${weather.precipitation.toStringAsFixed(1)}mm'),
Text('풍향: ${weather.windDirection.toStringAsFixed(0)}°'),
Text('풍속: ${weather.windSpeed.toStringAsFixed(1)}m/s'),
Text('자외선 지수: ${weather.uvIndex?.toStringAsFixed(1) ?? 'N/A'}'),
if (weather.fetchedAt != null) Text('갱신 시각: ${weather.fetchedAt}'),
],
),
),
);
}
}