Flutter高效数据加载与缓存插件simple_cached_future_builder的使用
Flutter高效数据加载与缓存插件simple_cached_future_builder的使用
特点
- 简化过程:使用该类可以简化在数据获取后构建小部件的过程。在最基础的情况下,可以减少编写代码的行数。
- 可选缓存:可以选择性地缓存获取的数据,从而减少在
build()
方法中调用的次数,尤其是在开发过程中频繁重建时。 - 管理缓存:可以选择使用默认管理器或自定义类来管理缓存。可以轻松地与任何数据库包结合使用,以更永久地存储数据。
开始使用
将 simple_cached_future_builder
添加为 pubspec.yaml
文件中的依赖项。
基本用法
SimpleCachedFutureBuilder<String>(
future: get(Uri.parse('https://www.boredapi.com/api/activity'))
.then((value) => value.body),
builder: (context, body) {
return Text(jsonDecode(body)['activity']);
},
)
相比 FutureBuilder
,你不再需要在加载或出现错误时返回一个组件。你可以省去一些重复的代码(例如 if (snapshot.connectionState == ConnectionState.done && snapshot.hasData)
的检查)。
FutureBuilder<String>(
future: get(Uri.parse('https://www.boredapi.com/api/activity'))
.then((value) => value.body),
builder: ((context, snapshot) {
if (snapshot.connectionState == ConnectionState.done && snapshot.hasData) {
return Text(jsonDecode(snapshot.data!)['activity']);
} else {
return Container();
}
}),
),
所有选项
SimpleCachedFutureBuilder<String>(
future: get(Uri.parse('https://www.boredapi.com/api/activity'))
.then((value) => value.body),
builder: (context, activityResponse) {
var activityData = jsonDecode(activityResponse);
return Text(activityData['activity']);
},
onLoadingWidget: const CircularProgressIndicator(),
onErrorWidget: (error) => const Icon(Icons.warning),
cache: SimpleCache(
tag: 'activitySuggestion',
validFor: const Duration(minutes: 3)),
cacheManager: MyCustomCacheManager(),
)
参数 | 示例 | 描述 |
---|---|---|
future |
get(Uri.parse('https://www.boredapi.com/api/activity')) |
必填:一个未来值。 |
builder |
builder: (context, activityResponse) => Text(activityResponse) |
必填:一个从未来方法返回的数据中生成小部件的方法。必须返回一个组件。 |
onLoadingWidget |
onLoadingWidget: const CircularProgressIndicator() |
可选:在加载期间显示的小部件。 |
onErrorWidget |
onErrorWidget: (error) => const Icon(Icons.warning) |
可选:如果获取数据失败或值为 null 时显示的小部件。 |
cache |
SimpleCache(tag: 'activitySuggestion', validFor: const Duration(minutes: 3)) |
可选:缓存值一段时间。 |
cacheManager |
BasicCacheManager() |
可选:处理缓存的管理器,例如手动清除缓存或在会话之间缓存它。 |
自定义缓存管理器
可以覆盖缓存管理器以使用不同于默认管理器(BasicCacheManager()
)的方式来处理缓存。
class MyCustomCacheManager extends CacheManager {
[@override](/user/override)
void clearCache() {
// TODO: 清除数据库
}
[@override](/user/override)
Future<bool> exists(SimpleCache tag) async {
// TODO: 检查值是否存在
}
[@override](/user/override)
void removeCache(SimpleCache tag) {
// TODO: 删除缓存
}
[@override](/user/override)
retrieveCache(SimpleCache tag) {
// TODO: 检索缓存
}
[@override](/user/override)
void storeCache(SimpleCache tag, data) {
// TODO: 存储缓存
}
}
额外信息
注意,默认缓存管理器将数据存储在 Map
中。这意味着每次应用程序完全重启时,所有数据都会被清除。
此外,如果缓存大量不同的大数据量,这可能会导致内存使用率较高。
默认管理器适用于临时的小数据,这些数据不需要在不同会话之间保留。对于所有其他用途,建议使用自定义缓存管理器。有关使用 Hive
的示例实现,请参阅 example/lib/main.dart
。
完整示例代码
import 'dart:async';
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:hive_flutter/hive_flutter.dart';
import 'package:http/http.dart';
import 'package:simple_cached_future_builder/simple_cached_future_builder.dart';
/// 一个[Hive]数据库来存储缓存值
Box? database;
void main() async {
await Hive.initFlutter();
database = await Hive.openBox('database');
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
[@override](/user/override)
Widget build(BuildContext context) {
return MaterialApp(
title: 'SimpleCachedFutureBuilder Example',
debugShowCheckedModeBanner: false,
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
useMaterial3: true,
),
home: const MyHomePage(title: 'SimpleCachedFutureBuilder Example'),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({super.key, required this.title});
final String title;
[@override](/user/override)
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
MyCustomCacheManager cacheManager = MyCustomCacheManager();
[@override](/user/override)
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Theme.of(context).colorScheme.inversePrimary,
title: Text(widget.title),
actions: [
IconButton(
tooltip: 'Clear all cache',
onPressed: () {
cacheManager.clearCache();
},
icon: const Icon(Icons.clear_all))
],
),
floatingActionButton: FloatingActionButton(
tooltip: 'Reload',
child: const Icon(Icons.refresh),
onPressed: () => setState(() {}),
),
body: Center(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
futureBuilderForCache(SimpleCache(
tag: 'activitySuggestion',
// 允许在10秒后获取新数据
validFor: const Duration(seconds: 10))),
futureBuilderForCache(
// 永远不获取新数据,保持第一次获取后的值
SimpleCache(tag: 'keepForEver')),
// 总是获取新数据
futureBuilderForCache(null),
],
),
));
}
SimpleCachedFutureBuilder futureBuilderForCache(SimpleCache? simpleCache) =>
SimpleCachedFutureBuilder<String>(
// 必填:一个未来值
future: get(Uri.parse('https://www.boredapi.com/api/activity'))
.then((value) => value.body),
// 必填:一个从未来方法返回的数据中生成小部件的方法。必须返回一个组件
builder: (context, activityResponse) {
var activityData = jsonDecode(activityResponse);
return Row(
mainAxisSize: MainAxisSize.min,
children: [
Text(activityData['activity']),
if (simpleCache != null) cacheInfoWidget(simpleCache)
],
);
},
// 可选:在数据获取期间显示的小部件
onLoadingWidget: const CircularProgressIndicator(),
// 可选:如果获取数据失败或值为 `null` 时显示的小部件
onErrorWidget: (error) => const Icon(Icons.warning),
// 可选:缓存值一段时间
cache: simpleCache,
// 可选:处理缓存的管理器,例如手动清除缓存或在会话之间缓存它
cacheManager: cacheManager,
);
/// 显示剩余时间并添加一个特定缓存项的删除按钮
Widget cacheInfoWidget(SimpleCache simpleCache) {
return Padding(
padding: const EdgeInsets.only(left: 8.0),
child: StreamBuilder<Duration?>(
stream: cacheManager.stream(simpleCache),
builder: (context, snapshot) {
return Row(
mainAxisSize: MainAxisSize.min,
children: [
Text(
snapshot.data?.inSeconds != null
? '${snapshot.data!.inSeconds} s'
: ' ',
style: Theme.of(context).textTheme.labelSmall,
),
IconButton(
tooltip: 'Delete this cache',
onPressed: (snapshot.data?.inSeconds ?? 0) > 0
? () {
cacheManager.removeCache(simpleCache);
}
: null,
icon: const Icon(Icons.delete))
],
);
},
),
);
}
}
/// 使用Hive的一个自定义缓存管理器的示例实现。
class MyCustomCacheManager extends CacheManager<String> {
[@override](/user/override)
void clearCache() {
super.clearCache();
database?.clear();
}
[@override](/user/override)
Future<bool> exists(SimpleCache tag) async {
var exists = database?.containsKey(tag.tag) ?? false;
return exists;
}
[@override](/user/override)
void removeCache(SimpleCache tag) {
super.removeCache(tag);
database?.delete(tag.tag);
}
[@override](/user/override)
String retrieveCache(SimpleCache tag) {
return database?.get(tag.tag, defaultValue: '');
}
[@override](/user/override)
void storeCache(SimpleCache tag, String data) {
database?.put(tag.tag, data);
}
}
更多关于Flutter高效数据加载与缓存插件simple_cached_future_builder的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html
1 回复