Flutter扩展功能插件bloc_ext的使用
Flutter扩展功能插件bloc_ext的使用
bloc_ext
是一个用于 bloc
中的 Cubit
的扩展包。CubitEx
引入了一些很酷的功能,现在每个 Cubit
都会有以下功能:
- 发送动作
- 过滤动作
- 添加效果
- 不同
Cubit
之间的通信(尽管Cubit
是独立的) - RxDart 的完整功能
请参阅 示例。此示例包含 counter
和 todo
页面,这些页面展示了 CubitEx
的开箱即用功能。
CounterCubit 示例
import 'package:bloc/bloc.dart';
import 'package:bloc_ext/bloc_ext.dart';
import 'package:rxdart/rxdart.dart';
import '../widgets/StreamConsumer.dart';
// 定义状态类
class CounterState extends Cubit<int> with CubitEx {
CounterState() : super(0);
// 增加计数
void inc() => emit(state + 1);
// 减少计数
void dec() => emit(state - 1);
// 异步增加计数
void asyncInc() async {
dispatch(Action(type: 'asyncInc'));
await Future.delayed(const Duration(seconds: 1));
inc();
}
// 定义异步增加的效果函数
EffectFun<int> get asyncIncBy => effect<int>((num$) =>
num$
.doOnData((_) => dispatch(Action(type: 'asyncInc')))
.delay(const Duration(seconds: 1))
.doOnData((by) => emit(state + by)));
// 获取计数流
Stream<SCResponse> get count$ => Rx.merge([
action$.whereType('asyncInc').mapTo(SCLoading()),
stream$.map((data) => data > 10
? SCError('Counter is out of the range.')
: SCData('$data')),
]);
}
TodoCubit 示例
import 'package:bloc/bloc.dart';
import 'package:bloc_ext/bloc_ext.dart';
import 'package:rxdart/rxdart.dart';
import '../api/todoApi.dart';
import './searchCategory.dart';
// 定义状态类
class TodoCubit extends Cubit<List<Todo>> with CubitEx {
TodoCubit() : super([]) {
$initEx();
}
@override
void onInit() {
loadTodos();
}
// 加载待办事项
void loadTodos() {
getTodos().listen(emit);
}
// 添加待办事项
void add(String description) {
addTodo(Todo(description: description))
.listen((todo) => emit([...state, todo]));
}
// 更新待办事项
void update(Todo todo) {
updateTodo(todo).listen(
(todo) => emit([
for (var item in state)
if (item.id == todo.id) todo else item,
]),
onError: (error) {
dispatch(TodoErrorAction(error));
});
}
// 删除待办事项
void remove(Todo todo) {
removeTodo(todo).listen(
(todo) => emit(state.where((item) => item.id != todo.id).toList()));
}
// 获取活跃待办事项信息流
Stream<String> get activeTodosInfo$ => stream$
.map((todos) => todos.where((todo) => !todo.completed).toList())
.map((todos) => '${todos.length} items left');
// 结合多个Cubit (TodoCubit, SearchCategoryCubit) 并返回单个待办事项流
Stream<List<Todo>> get todo$ =>
Rx.combineLatest3<List<Todo>, SearchCategory, String, List<Todo>>(
stream$,
remoteStream<SearchCategoryCubit, SearchCategory>(),
action$
.isA<SearchInputAction>()
.debounceTime(const Duration(milliseconds: 320))
.map((action) => action.searchText)
.startWith(''),
(todos, category, searchText) {
if (searchText.isNotEmpty) {
todos = todos.where((todo) => todo.description
.toLowerCase()
.contains(searchText.toLowerCase()))
.toList();
}
switch (category) {
case SearchCategory.Active:
return todos.where((todo) => !todo.completed).toList();
case SearchCategory.Completed:
return todos.where((todo) => todo.completed).toList();
default:
return todos;
}
});
}
// 定义错误动作类
class TodoErrorAction extends Action {
final dynamic error;
TodoErrorAction(this.error);
}
// 定义搜索输入动作类
class SearchInputAction extends Action {
final String searchText;
SearchInputAction(this.searchText);
}
SearchCategoryCubit 示例
import 'package:bloc/bloc.dart';
import 'package:bloc_ext/bloc_ext.dart';
// 定义搜索类别枚举
enum SearchCategory { All, Active, Completed }
// 定义搜索类别Cubit
class SearchCategoryCubit extends Cubit<SearchCategory> with CubitEx {
SearchCategoryCubit() : super(SearchCategory.All) {
$initEx();
}
// 设置搜索类别
void setCategory(SearchCategory category) => emit(category);
}
主应用示例
import 'package:example/states/counter.dart';
import 'package:flutter/material.dart';
import 'package:get/instance_manager.dart';
import 'package:get/route_manager.dart';
import './states/todo.dart';
import './pages/counterPage.dart';
import './pages/todoPage.dart';
import './states/searchCategory.dart';
void main() {
runApp(GetMaterialApp(
smartManagement: SmartManagement.keepFactory,
debugShowCheckedModeBanner: false,
getPages: [
GetPage(
name: '',
page: () => CounterPage(),
binding: BindingsBuilder(() {
Get.lazyPut(() => CounterState());
})),
GetPage(
name: '/todo',
page: () => TodoPage(),
transition: Transition.zoom,
binding: BindingsBuilder(() {
Get.put<TodoState>(TodoState(), permanent: true);
Get.put<SearchCategoryState>(SearchCategoryState(), permanent: true);
}))
],
initialRoute: '',
));
}
更多关于Flutter扩展功能插件bloc_ext的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter扩展功能插件bloc_ext的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
bloc_ext
是一个用于 Flutter 的扩展功能插件,旨在简化 flutter_bloc
的使用,并提供一些额外的功能来增强开发体验。bloc_ext
可以帮助你更容易地管理 BLoC(Business Logic Component)状态,减少样板代码,并提高代码的可读性和可维护性。
以下是一些常见的 bloc_ext
功能和使用方法:
1. 安装 bloc_ext
首先,你需要在 pubspec.yaml
文件中添加 bloc_ext
依赖:
dependencies:
flutter:
sdk: flutter
bloc_ext: ^0.1.0 # 请检查最新版本
然后运行 flutter pub get
来安装依赖。
2. 基本用法
bloc_ext
提供了一些扩展方法和工具来简化 flutter_bloc
的使用。以下是一些常见的用法示例:
2.1 简化 BlocProvider
的创建
bloc_ext
提供了一个 BlocProvider.ext
方法来简化 BlocProvider
的创建:
import 'package:flutter/material.dart';
import 'package:bloc_ext/bloc_ext.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
class MyBloc extends Cubit<int> {
MyBloc() : super(0);
void increment() => emit(state + 1);
}
class MyApp extends StatelessWidget {
[@override](/user/override)
Widget build(BuildContext context) {
return BlocProvider.ext(
create: (context) => MyBloc(),
child: MaterialApp(
home: MyHomePage(),
),
);
}
}
2.2 简化 BlocBuilder
的使用
bloc_ext
提供了一个 BlocBuilder.ext
方法来简化 BlocBuilder
的使用:
class MyHomePage extends StatelessWidget {
[@override](/user/override)
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Bloc Ext Example'),
),
body: Center(
child: BlocBuilder.ext<MyBloc, int>(
builder: (context, state) {
return Text('Count: $state');
},
),
),
floatingActionButton: FloatingActionButton(
onPressed: () => context.read<MyBloc>().increment(),
child: Icon(Icons.add),
),
);
}
}
2.3 简化 BlocListener
的使用
bloc_ext
提供了一个 BlocListener.ext
方法来简化 BlocListener
的使用:
class MyHomePage extends StatelessWidget {
[@override](/user/override)
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Bloc Ext Example'),
),
body: Center(
child: BlocListener.ext<MyBloc, int>(
listener: (context, state) {
if (state == 5) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('Count reached 5!')),
);
}
},
child: BlocBuilder.ext<MyBloc, int>(
builder: (context, state) {
return Text('Count: $state');
},
),
),
),
floatingActionButton: FloatingActionButton(
onPressed: () => context.read<MyBloc>().increment(),
child: Icon(Icons.add),
),
);
}
}