设计思路
- 集中管理网络请求:使用一个单独的服务类来处理所有网络请求,这样可以在一个地方统一设置超时时间等配置。
- 状态管理:
- Provider:利用
ChangeNotifier
或Riverpod
等方式来管理网络请求状态。将网络请求的状态(加载中、成功、失败)封装在一个模型类中,通过Provider
提供给各个页面。
- Bloc:创建不同的
Bloc
来处理不同类型的网络请求。每个Bloc
管理自身请求的状态,如Loading
、Success
、Error
状态,通过BlocBuilder
在页面上进行状态渲染。
- 超时处理:在网络请求服务类中设置超时时间,当请求超时时,通过状态管理机制更新状态,通知页面显示超时错误提示。
以Bloc为例的核心代码
- 定义状态
// 定义网络请求状态
enum NetworkRequestStatus { loading, success, error }
class NetworkRequestState {
final NetworkRequestStatus status;
final dynamic data;
final String? errorMessage;
NetworkRequestState({
required this.status,
this.data,
this.errorMessage,
});
}
- 定义Bloc
import 'dart:async';
import 'package:bloc/bloc.dart';
class NetworkRequestBloc extends Bloc<NetworkRequestEvent, NetworkRequestState> {
NetworkRequestBloc() : super(NetworkRequestState(status: NetworkRequestStatus.loading)) {
on<FetchDataEvent>(_fetchData);
}
Future<void> _fetchData(FetchDataEvent event, Emitter<NetworkRequestState> emit) async {
emit(state.copyWith(status: NetworkRequestStatus.loading));
try {
// 模拟网络请求,设置超时时间
final response = await Future.delayed(const Duration(seconds: 5), () => {'key': 'value'});
emit(state.copyWith(status: NetworkRequestStatus.success, data: response));
} catch (e) {
emit(state.copyWith(status: NetworkRequestStatus.error, errorMessage: '请求超时或出现错误'));
}
}
}
- 定义事件
abstract class NetworkRequestEvent {}
class FetchDataEvent extends NetworkRequestEvent {}
- 在页面中使用
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
class MyPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return BlocProvider(
create: (context) => NetworkRequestBloc(),
child: Scaffold(
appBar: AppBar(title: Text('网络请求示例')),
body: BlocBuilder<NetworkRequestBloc, NetworkRequestState>(
builder: (context, state) {
if (state.status == NetworkRequestStatus.loading) {
return Center(child: CircularProgressIndicator());
} else if (state.status == NetworkRequestStatus.success) {
return Text('数据: ${state.data}');
} else if (state.status == NetworkRequestStatus.error) {
return Center(child: Text(state.errorMessage?? '未知错误'));
}
return Container();
},
),
floatingActionButton: FloatingActionButton(
onPressed: () => context.read<NetworkRequestBloc>().add(FetchDataEvent()),
child: Icon(Icons.refresh),
),
),
);
}
}