pubspec.yaml
dependencies:
http: ^0.13.5
我們這邊使用中央氣象局的氣象開放資料平台
我們先註冊後獲取API授權碼
先來看一下API Docs
我們這邊要使用現在天氣觀測
測試並觀察
新增todo\lib\models\weather_model.dart
import 'package:meta/meta.dart';
import 'dart:convert';
class WeatherModel {
WeatherModel({
required this.location,
required this.temp,
required this.time,
});
final String location;
final String temp;
final String time;
WeatherModel copyWith({
String? location,
String? temp,
String? time,
}) =>
WeatherModel(
location: location ?? this.location,
temp: temp ?? this.temp,
time: time ?? this.time,
);
factory WeatherModel.fromJson(String str) =>
WeatherModel.fromMap(json.decode(str));
String toJson() => json.encode(toMap());
factory WeatherModel.fromMap(Map<String, dynamic> json) => WeatherModel(
location: json["location"],
temp: json["temp"],
time: json["time"],
);
Map<String, dynamic> toMap() => {
"location": location,
"temp": temp,
"time": time,
};
}
新增todo\lib\services\weather_services.dart
import 'dart:developer';
import 'dart:io';
import 'dart:convert';
import 'package:todo/models/weather_model.dart';
import 'package:http/http.dart' as http;
class WeatherService {
Future<WeatherModel?> getWeather() async {
WeatherModel weather;
String authorization = "CWB-DB6D5CC3-504F-4A00-ADFC-3730E9A2C95D";
String stationId = "466920";
String elementName = "TEMP";
String parameterName = "CITY";
try {
var headers = {'content-type': 'application/json'};
var url = Uri.parse(
'https://opendata.cwb.gov.tw/api/v1/rest/datastore/O-A0003-001?Authorization=CWB-DB6D5CC3-504F-4A00-ADFC-3730E9A2C95D&stationId=466920&elementName=TEMP¶meterName=CITY');
final response = await http.get(url, headers: headers);
if (response.statusCode == 200) {
var temp = json.decode(response.body);
// dynamic _temp2 = temp["records"]["location"][0];
var weatherType = json.encode({
"location": temp["records"]["location"][0]["locationName"],
"temp": temp["records"]["location"][0]["weatherElement"][0]
["elementValue"],
"time": temp["records"]["location"][0]["time"]["obsTime"],
}).toString();
weather = WeatherModel.fromJson(weatherType);
log('OK');
return weather;
} else {
log('請求失敗');
}
} catch (err) {
log('post fetch and set catch error', error: err);
}
}
}
創建todo\lib\states\Iweather_state.dart
import 'package:todo/models/weather_model.dart';
abstract class IWeatherState {
WeatherModel getWeather();
}
todo\lib\states\weather_state.dart
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:todo/models/weather_model.dart';
import 'package:todo/services/weather_services.dart';
import 'package:todo/states/Iweather_state.dart';
class WeatherState extends StateNotifier<WeatherModel>
implements IWeatherState {
WeatherState(WeatherModel? weatherModel)
: super(
weatherModel ?? WeatherModel(location: "", temp: "", time: ""),
);
@override
Future<WeatherModel> getWeather() async {
// TODO: implement getWeather
final weather = await WeatherService().getWeather();
if (weather != null) {
return weather;
} else {
throw Exception();
}
}
}
final weatherProvider =
StateNotifierProvider<WeatherState, WeatherModel>((ref) {
return WeatherState(null);
});
新增todo\lib\ui\widgets\weather_item_widget.dart
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/src/foundation/key.dart';
import 'package:flutter/src/widgets/framework.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:todo/models/weather_model.dart';
import 'package:todo/services/weather_services.dart';
import 'package:todo/states/weather_state.dart';
class WeatherItem extends ConsumerWidget {
const WeatherItem({Key? key}) : super(key: key);
@override
Widget build(BuildContext context, WidgetRef ref) {
final weather = ref.read(weatherProvider.notifier).getWeather();
// WeatherModel _weather;
return FutureBuilder(
builder: (context, AsyncSnapshot<WeatherModel?> snapshot) {
if (snapshot.hasData) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('Today Weather : ${snapshot.data!.location.toString()}'),
Text(
'Time: ${snapshot.data!.time.toString()} / Temp: ${snapshot.data!.temp.toString()}'),
],
);
} else if (snapshot.hasError) {
return Text('${snapshot.error.toString()}');
} else {
return const Center(
child: CircularProgressIndicator(),
);
}
},
future: weather);
}
}
到我們的todo\lib\ui\screens\home_screen.dart
加入widget
...
class _HomeScreenState extends State<HomeScreen> {
...
return CustomScrollView(
controller: _trackingScrollController,
slivers: [
SliverAppBar(
title: Text('Home Screen'),
),
SliverToBoxAdapter(
child: WeatherItem(),
),
SliverToBoxAdapter(
child: TodoList(),
),
SliverToBoxAdapter(child: AddTodo(testTodo)),
],
);
}
}
測試: