今天要介紹如何把資料透過使用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下設定三個靜態方法
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"),
)
],
),
),
);
}