Flutter响应式编程与状态管理插件rxdart_bloc的使用
以下是关于“Flutter响应式编程与状态管理插件rxdart_bloc的使用”的完整示例demo内容:
截图 #
成功 | 错误 | 架构 |
---|---|---|
开始使用 #
在项目中使用 null-safety
版本:
rxdart_bloc: ^1.0.14
将依赖添加到您的项目并开始使用 rxdart_bloc。
导入包:
import 'package:rxdart_bloc/rxdart_bloc.dart';
用法 #
要使用此插件,将 rxdart_bloc 添加为您的 pubspec.yaml 文件中的依赖项。
示例 #
以下是一个示例,展示了如何使用该插件。
main.dart #
import 'package:flutter/material.dart';
import 'package:rxdart_bloc/bloc_provider.dart';
import ‘products/bloc/products_bloc.dart’;
import ‘products/view/products_view.dart’;
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: ‘Flutter rxdart_bloc 示例’,
home: BlocProvider(bloc: ProductsBloc(), child: const ProductsView()),
);
}
}
products_view.dart #
import 'package:flutter/material.dart';
import 'package:rxdart_bloc/rxdart_bloc.dart';
import ‘…/bloc/products_bloc.dart’;
import ‘…/model/products_response_model.dart’;
import ‘widget/products_item_widget.dart’;
class ProductsView extends StatefulWidget {
const ProductsView({Key? key}) : super(key: key);
@override
State<ProductsView> createState() => _ProductsViewState();
}
class _ProductsViewState extends State<ProductsView> {
late ProductsBloc _bloc;
@override
void initState() {
_bloc = BlocProvider.of<ProductsBloc>(context);
_bloc.getProducts();
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text(‘产品列表’),),
body: StreamBuilder<GetAllProductsResponseModel>(
stream: _bloc.successStream,
builder: (context, snapshot) {
return StreamingResult(
subject: _bloc.requestStateSubject,
successWidget: ListView.builder(
itemCount: snapshot.data?.products?.length,
padding: const EdgeInsets.all(16),
itemBuilder: (context, index) {
return ProductsItemWidget(
content: snapshot.data?.products?[index],
);
}),
retry: () =>
_bloc.getProducts(),
);
}
),
);
}
}
products_bloc.dart #
import 'package:rxdart_bloc/rxdart_bloc.dart';
import '../../../network/network.dart';
import '../../models/error_model.dart';
import '../model/products_response_model.dart';
import '../repo/products_repo.dart';
class ProductsBloc extends BaseBloc
with RxdartBlocState<GetAllProductsResponseModel, ErrorModel> {
BehaviorSubject<RequestState> requestStateSubject = BehaviorSubject.seeded(
RequestState(status: RequestStatus.init, message: ‘初始状态’));
final ProductsRepo _countriesRepo =
ProductsRepo(Network(‘https://dummyjson.com/’));
Future getProducts() async {
requestStateSubject.sink
.add(RequestState(status: RequestStatus.loading, message: ‘加载中’));
var model = await _countriesRepo.getProducts();
if (model is GetAllProductsResponseModel) {
super.successSubject.sink.add(model);
requestStateSubject.sink
.add(RequestState(status: RequestStatus.success, message: '成功'));
}
if (model is ErrorModel) {
super.errorSubject.sink.add(model);
requestStateSubject.sink.add(RequestState(
status: RequestStatus.error, message: model.message ?? '错误'));
}
}
@override
void dispose() {
requestStateSubject.close();
}
}
products_repo_interface.dart #
import 'package:rxdart_bloc/base_model.dart';
abstract interface class ProductsRepoInterface {
Future<BaseModel> getProducts();
}
products_repo.dart #
import 'package:rxdart_bloc/base_model.dart';
import '../../../network/network.dart';
import '../../models/error_model.dart';
import '../model/products_response_model.dart';
import 'products_repo_interface.dart';
class ProductsRepo implements ProductsRepoInterface {
final Network _network;
ProductsRepo(this._network);
@override
Future<BaseModel> getProducts() async {
try {
var response =
await _network.request(HttpMethod.get, endpoint: ‘products’);
return GetAllProductsResponseModel.fromJson(response?.data);
} catch (e) {
return ErrorModel.fromJson(e as dynamic);
}
}
}
rxdart_bloc widgets #
BlocProvider #
BlocProvider 是一个 Flutter 小部件,它向其子级提供一个 bloc。
BlocProvider(bloc: ProductsBloc(), child: const ProductsView());
MultiBlocProvider #
MultiBlocProvider 是一个 Flutter 小部件,它向其子级提供多个 bloc。
MultiBlocProvider<List<BaseBloc>>(
blocs: [
Bloc1(),
Bloc2(),
], child: const ProductsView()
);
StreamingResult #
StreamingResult 是一个 Flutter 小部件,它返回请求流的结果。您可以提供自定义的 initWidget, successWidget, emptyWidget, errorWidget, retry function。
StreamingResult(
subject: _bloc.requestStateSubject,
// initWidget: const Center(child: Text('初始')),
successWidget: ListView.builder(
itemCount: snapshot.data?.products?.length,
padding: const EdgeInsets.all(16),
itemBuilder: (context, index) {
return ProductsItemWidget(content: snapshot.data?.products?[index]);
}),
// emptyWidget: const Center(child: Text('空')),
// errorWidget: const Center(child: Text('错误')),
retry: () => _bloc.getProducts(),
);
声明 bloc #
late ProductsBloc _bloc;
初始化 bloc #
[@override](/user/override)
void initState() {
_bloc = BlocProvider.of<ProductsBloc>(context);
_bloc.getProducts();
super.initState();
}
改进 #
通过报告错误、提交新功能的想法或其他任何您想分享的内容来帮助改进。
- 请在 GitHub 上 写一个问题。 ✏️
- 别忘了给此包点个赞 ✌️
更多 #
查看我在 pub.dev 上的其他有用的包。
更多关于Flutter响应式编程与状态管理插件rxdart_bloc的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter响应式编程与状态管理插件rxdart_bloc的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,以下是一个关于如何在Flutter中使用rxdart
和bloc
进行响应式编程和状态管理的代码示例。这个示例将展示如何创建一个简单的计数器应用,其中包括状态的定义、Bloc的创建、事件的处理以及UI的更新。
1. 添加依赖
首先,在你的pubspec.yaml
文件中添加rxdart
和flutter_bloc
依赖:
dependencies:
flutter:
sdk: flutter
flutter_bloc: ^8.0.0 # 确保版本是最新的
rxdart: ^0.27.0 # 确保版本是最新的
2. 定义状态
创建一个枚举来表示计数器的状态:
// counter_state.dart
part of 'counter_bloc.dart';
abstract class CounterState {}
class CounterInitialState extends CounterState {}
class CounterIncrementedState extends CounterState {
final int count;
CounterIncrementedState({required this.count});
}
3. 定义事件
创建一个类来表示计数器的事件:
// counter_event.dart
part of 'counter_bloc.dart';
abstract class CounterEvent {}
class CounterIncrementedEvent extends CounterEvent {}
4. 创建Bloc
使用rxdart
的BehaviorSubject
来管理状态流,并处理事件:
// counter_bloc.dart
import 'package:bloc/bloc.dart';
import 'package:rxdart/rxdart.dart';
import 'counter_event.dart';
import 'counter_state.dart';
part 'counter_event.dart';
part 'counter_state.dart';
class CounterBloc extends Bloc<CounterEvent, CounterState> {
CounterBloc() : super(CounterInitialState()) {
on<CounterIncrementedEvent>((event, emit) {
emit(CounterIncrementedState(count: state is CounterIncrementedState
? (state as CounterIncrementedState).count! + 1
: 1));
});
}
}
5. 创建UI
在Flutter应用中,使用BlocBuilder
来监听状态变化并更新UI:
// main.dart
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'counter_bloc.dart';
void main() {
runApp(BlocProvider(
create: (_) => CounterBloc(),
child: MyApp(),
));
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(title: Text('Flutter Counter with Bloc')),
body: Center(
child: BlocBuilder<CounterBloc, CounterState>(
builder: (context, state) {
if (state is CounterInitialState) {
return Text('Press the button to start');
} else if (state is CounterIncrementedState) {
return Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'You have pushed the button this many times:',
),
Text(
'${state.count}',
style: Theme.of(context).textTheme.headline4,
),
],
);
} else {
return Text('Unknown state');
}
},
),
),
floatingActionButton: FloatingActionButton(
onPressed: () {
context.read<CounterBloc>().add(CounterIncrementedEvent());
},
tooltip: 'Increment',
child: Icon(Icons.add),
),
),
);
}
}
总结
以上代码展示了如何在Flutter中使用rxdart
和bloc
进行响应式编程和状态管理。我们定义了状态、事件和Bloc,并在UI中使用BlocBuilder
来监听状态变化。当用户点击浮动按钮时,会触发CounterIncrementedEvent
事件,Bloc会处理该事件并更新状态,UI随之更新。
这只是一个简单的示例,实际应用中你可能会有更复杂的状态和事件处理逻辑。希望这个示例能帮助你理解如何在Flutter中使用rxdart
和bloc
进行状态管理。