iT邦幫忙

2022 iThome 鐵人賽

DAY 22
0
自我挑戰組

30天學習flutter系列 第 22

22.flutter的持久化存儲(五)

  • 分享至 

  • xImage
  •  

Restful API

安裝依賴

pubspec.yaml

dependencies:
  http: ^0.13.5

https://ithelp.ithome.com.tw/upload/images/20221007/20108931I1KNiHwNOd.png

獲取API

我們這邊使用中央氣象局的氣象開放資料平台

我們先註冊後獲取API授權碼
https://ithelp.ithome.com.tw/upload/images/20221007/20108931er2mPFnGoX.png

先來看一下API Docs

我們這邊要使用現在天氣觀測
https://ithelp.ithome.com.tw/upload/images/20221007/20108931lKPuEFeALE.png

測試並觀察
https://ithelp.ithome.com.tw/upload/images/20221007/20108931pRHf7aKPiE.png

https://ithelp.ithome.com.tw/upload/images/20221007/20108931Xe967p4twS.png

WeatherModel

新增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,
      };
}

WeatherService

新增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&parameterName=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);
    }
  }
}

WeatherState

創建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);
});

UI

新增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)),
      ],
    );
  }
}

測試:
https://ithelp.ithome.com.tw/upload/images/20221008/20108931zgFVDZ18fx.png


上一篇
21.flutter的持久化存儲(四)
下一篇
23.關於flutter的非同步處理(一)
系列文
30天學習flutter30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言