iT邦幫忙

2022 iThome 鐵人賽

DAY 12
0
Mobile Development

在 Flutter 開發旅程的手札系列 第 12

Flutter Package - 把API資料存到手機的Local Storage

  • 分享至 

  • xImage
  •  

今天要介紹如何把資料透過使用shared_preferences來儲存資料在手機裡,這在開發APP中是非常實用的小技巧,我們將資料存到手機內,能避免每一次需要資料時,必須重複打API拿到特定的資料

輸入指令安裝套件

 flutter pub add shared_preferences

在下方的程式碼中,我會使用Flutter Package - 串接api(二)裡的結構再進行調整的,建議大家先實作這一篇的內容,會比較容易懂下方的範例程式碼


新增或開啟post_data_response.dart,在加入下方程式碼,把物件轉為Map的格式

在PostDataResponse class最下方加入
Map<String, dynamic> toJson() => _$PostDataResponseToJson(this);

在PostData class加入
Map<String, dynamic> toJson() => _$PostDataToJson(this);

完整程式碼

import 'package:json_annotation/json_annotation.dart';

part 'post_data_response.g.dart';

@JsonSerializable()
class PostDataResponse {
  PostData data;
  PostDataResponse({
    required this.data,
  });
  factory PostDataResponse.fromJson(Map<String, dynamic> json) => _$PostDataResponseFromJson(json);
  Map<String, dynamic> toJson() => _$PostDataResponseToJson(this);
}

@JsonSerializable()
class PostData {
  String content;
  PostData({
    required this.content,
  });
  factory PostData.fromJson(Map<String, dynamic> json) => _$PostDataFromJson(json);
  Map<String, dynamic> toJson() => _$PostDataToJson(this);
}



建立一個record_service.dart檔案
在這檔案我們會在RecordService class下設定三個靜態方法

  1. setPostDataRecord:存取資料到手機裡
  2. getPostDataRecord:讀取手機裡的資料
  3. resetPostDataRecord:將資料從手機裡刪除
import 'dart:convert';

import 'package:flutter_api_demo/common/models/response/post_data_response.dart';
import 'package:shared_preferences/shared_preferences.dart';

class RecordService {
  static Future<void> setPostDataRecord(PostDataResponse postDataRecord) async {
    final prefs = await SharedPreferences.getInstance();
    prefs.setString("postDataRecord", jsonEncode(postDataRecord.toJson()));
  }

  static Future<PostDataResponse?> getPostDataRecord() async {
    final prefs = await SharedPreferences.getInstance();
    var postDataRecord = prefs.getString("postDataRecord");
    if (postDataRecord == null) {
      return null;
    }
    return PostDataResponse.fromJson(jsonDecode(postDataRecord));
  }

  static Future<void> resetPostDataRecord() async {
    final pref = await SharedPreferences.getInstance();
    var postDataRecord = pref.getString("postDataRecord");
    if (postDataRecord != null) {
      await pref.remove("postDataRecord");
    }
  }
}


在StatefulWidget裡,建立controller

TextEditingController controller = TextEditingController();

在Widget build(BuildContext context)內輸入下方程式碼

 Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Padding(
              padding: const EdgeInsets.all(20),
              child: TextField(controller: controller, decoration: InputDecoration(hintText: '請輸入要存進API的資料')),
            ),
            ElevatedButton(
              onPressed: () async {
                final apiResponse =
                    await RepositoryProvider.of<AppRepository>(context).postApiData(PostDataRequest(content: controller.text));
                await RecordService.setPostDataRecord(apiResponse);
                ScaffoldMessenger.of(context).showSnackBar(const SnackBar(
                  content: Text("setPostDataRecord"),
                ));
              },
              child: const Text("Set Data Button"),
            ),
            ElevatedButton(
              onPressed: () async {
                final getPostDataRecord = await RecordService.getPostDataRecord();
                ScaffoldMessenger.of(context).showSnackBar(SnackBar(
                  content: Text(getPostDataRecord?.data.content ?? "No Data"),
                ));
              },
              child: const Text("Get Data Button"),
            ),
            ElevatedButton(
              onPressed: () async {
                await RecordService.resetPostDataRecord();
                final getPostDataRecord = await RecordService.getPostDataRecord();
                ScaffoldMessenger.of(context).showSnackBar(const SnackBar(
                  content: Text("resetPostDataRecord"),
                ));
              },
              child: const Text("Reset Data Button"),
            )
          ],
        ),
      ),
    );
  }

Demo 把API資料存到手機裡


上一篇
Flutter Widget - 製作搜尋列表
下一篇
Flutter Widget - 不使用StatefulWidget改用ValueListenableBuilder更新畫面
系列文
在 Flutter 開發旅程的手札30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言