Flutter数据获取插件fetcher的使用
Flutter数据获取插件fetcher的使用
fetcher
是一个用于处理异步任务(如网络请求)UI状态(加载、错误和数据)的Flutter插件。它遵循KISS原则,提供了简单易用的API。
主要功能
- Minimalist library: 大部分使用原生Flutter组件和逻辑。
- Ready to use: 提供默认小部件。
- 基本使用非常简单直接,同时支持高级用法。
- 全局配置与本地覆盖。
- 错误和重试处理,带有常见的用户体验行为。
- 可以连接到错误报告服务。
- 在状态之间进行淡入淡出过渡以允许平滑的UI。
- 可选组件与BLoC模式一起使用(推荐)。
主要小部件
FetchBuilder
用于获取然后显示数据的小部件,处理加载、错误和数据状态,并包含重试系统。
SubmitBuilder
用于提交数据的小部件,处理加载和错误状态,并在加载时显示屏障以防止用户交互。
其他小部件
EventFetchBuilder
: 监听EventStream
并显示数据。PagedListViewFetcher
: 带有无限滚动的分页版本的FetchBuilder
。SubmitFormBuilder
: 提交数据并自动表单验证。AsyncEditBuilder
: 获取然后显示数据,并在需要时提交更改。
使用示例
获取数据
FetchBuilder<Weather>(
task: api.getWeather,
builder: (context, weather) => Text('Weather: ${weather.temperature}')
)
其中getWeather
是一个返回Future<Weather>
的异步函数。
自定义配置
FetchBuilder<Weather>(
task: api.getWeather,
config: FetcherConfig(
fetchingBuilder: (context) => const CircularProgressIndicator(),
),
builder: (context, weather) => Text('Weather: ${weather.temperature}')
)
提交数据
SubmitBuilder<void>(
task: () => api.submitData('new data value'),
onSuccess: (_) => Navigator.pop(context),
builder: (context, runTask) => ElevatedButton(
onPressed: runTask,
child: const Text('Submit'),
),
)
完整示例:新闻阅读器应用
1. 获取数据
首先,构建bloc并添加方法从服务器获取最新文章:
import 'package:fetcher/fetcher_bloc.dart';
class NewsReaderBloc with Disposable {
Future<NewsArticle> fetchArticle() async {
await Future.delayed(const Duration(seconds: 2));
return NewsArticle('Title 1', 'Random content generated for page 1, at ${DateTime.now()}');
}
}
class NewsArticle {
const NewsArticle(this.title, this.content);
final String title;
final String content;
}
在UI方面,创建一个新的stateful widget来持有bloc实例:
import 'package:fetcher/fetcher_bloc.dart';
import 'package:flutter/material.dart';
import 'news_reader.bloc.dart';
class NewsReaderPage extends StatefulWidget {
const NewsReaderPage({super.key});
@override
State<NewsReaderPage> createState() => _NewsReaderPageState();
}
class _NewsReaderPageState extends State<NewsReaderPage> with BlocProvider<NewsReaderPage, NewsReaderBloc> {
@override
NewsReaderBloc initBloc() => NewsReaderBloc();
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('News reader #1'),
),
body: FetchBuilder<NewsArticle>(
task: bloc.fetchArticle,
builder: (context, article) {
return Padding(
padding: const EdgeInsets.all(20),
child: Column(
children: [
Text(article.title, style: Theme.of(context).textTheme.headlineSmall),
const SizedBox(height: 15),
Text(article.content, style: Theme.of(context).textTheme.bodyLarge),
],
),
);
}
),
);
}
}
2. 动态小部件
为了处理用户交互并更新界面,可以使用DataStream
和DataStreamBuilder
:
enum ArticleVote { like, dislike }
class NewsReaderBloc with Disposable {
final selectedVote = DataStream<ArticleVote?>(null);
@override
void dispose() {
selectedVote.close();
super.dispose();
}
void selectVote(ArticleVote vote) => selectedVote.add(vote, skipSame: true);
}
// UI side
DataStreamBuilder<ArticleVote?>(
stream: bloc.selectedVote,
builder: (context, selectedVote) {
return ToggleButtons(
isSelected: [
selectedVote == ArticleVote.like,
selectedVote == ArticleVote.dislike,
],
onPressed: (index) => bloc.selectVote(index == 0 ? ArticleVote.like : ArticleVote.dislike),
children: const [Icon(Icons.thumb_up), Icon(Icons.thumb_down)],
);
},
)
3. 提交数据
使用SubmitBuilder
提交用户的投票:
Future<ArticleVote> voteArticle([ArticleVote? vote]) async {
vote ??= selectedVote.value;
if (vote == null) throw Exception('Select a vote first');
await Future.delayed(const Duration(seconds: 1));
return vote;
}
Widget build(BuildContext context) {
return SubmitBuilder<ArticleVote>(
task: bloc.voteArticle,
onSuccess: (vote) {
ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text('Voted successfully: ${vote.name}'), backgroundColor: Colors.green));
Navigator.of(context).pushReplacement(MaterialPageRoute(builder: (context) => NewsReaderPage()));
},
builder: (context, runTask) {
return ElevatedButton(onPressed: runTask, child: const Text('Vote'));
}
);
}
开始使用
- 在
pubspec.yaml
中添加依赖:dependencies: fetcher: ^latest_version
- 导入包:
import 'package:fetcher/fetcher.dart'; // 或者使用 BLoC 模式 import 'package:fetcher/fetcher_bloc.dart';
更多详细信息和完整示例代码请参考官方GitHub仓库。
更多关于Flutter数据获取插件fetcher的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter数据获取插件fetcher的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,下面是一个关于如何使用Flutter数据获取插件fetcher
的示例代码。fetcher
是一个假设的数据获取插件,用于演示目的,实际中可能需要根据具体插件的文档进行调整。
首先,确保在pubspec.yaml
文件中添加fetcher
依赖项(假设该插件存在):
dependencies:
flutter:
sdk: flutter
fetcher: ^x.y.z # 替换为实际的版本号
然后,运行flutter pub get
来获取依赖项。
接下来,在Flutter应用中使用fetcher
插件进行数据获取。以下是一个简单的示例,展示如何配置和使用fetcher
来获取数据:
import 'package:flutter/material.dart';
import 'package:fetcher/fetcher.dart'; // 假设fetcher插件的导入路径
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Fetcher Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: DataFetcherScreen(),
);
}
}
class DataFetcherScreen extends StatefulWidget {
@override
_DataFetcherScreenState createState() => _DataFetcherScreenState();
}
class _DataFetcherScreenState extends State<DataFetcherScreen> {
Fetcher? _fetcher;
String? _data;
bool _isLoading = false;
@override
void initState() {
super.initState();
_initializeFetcher();
}
void _initializeFetcher() {
// 假设Fetcher有一个配置和初始化的方法
_fetcher = Fetcher(
endpoint: 'https://api.example.com/data', // 替换为实际API端点
onResponse: (response) {
setState(() {
_data = response.body; // 假设response有一个body属性
_isLoading = false;
});
},
onError: (error) {
setState(() {
_data = 'Error: $error';
_isLoading = false;
});
},
);
// 开始获取数据
_fetchData();
}
void _fetchData() {
setState(() {
_isLoading = true;
});
_fetcher?.fetch(); // 假设Fetcher有一个fetch方法来获取数据
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Fetcher Demo'),
),
body: Center(
child: _isLoading
? CircularProgressIndicator()
: Text(
_data ?? 'No data yet',
style: TextStyle(fontSize: 20),
),
),
floatingActionButton: FloatingActionButton(
onPressed: _fetchData,
tooltip: 'Fetch Data',
child: Icon(Icons.refresh),
),
);
}
}
在这个示例中:
- 依赖项:在
pubspec.yaml
文件中添加了fetcher
依赖项。 - 配置Fetcher:在
_initializeFetcher
方法中配置了Fetcher
实例,包括API端点、响应处理函数和错误处理函数。 - 获取数据:通过调用
_fetcher?.fetch()
方法开始数据获取,并在获取过程中显示加载指示器。 - UI展示:在UI中显示获取到的数据或错误信息,并提供一个刷新按钮来重新获取数据。
请注意,这个示例假设fetcher
插件有一个类似Fetcher
的类,并且该类具有endpoint
、onResponse
、onError
和fetch
等方法和属性。实际使用中,需要根据fetcher
插件的实际API文档进行调整。