Flutter状态管理插件onix_flutter_bloc的使用

发布于 1周前 作者 eggper 来自 Flutter

Flutter状态管理插件onix_flutter_bloc的使用

该插件包含了一些设计用于改进使用BLoC状态管理体验的基础类。

BLoC (Cubit)

自定义BLoC是一种常规BLoC,并且具有一个额外的事件类型称为Single Result。Single Result旨在在UI中调用一次性功能(如显示对话框、导航等)。

基本步骤

1. 创建BLoC类

扩展你的BLoC类为BaseBloc

class ExampleScreenBloc extends BaseBloc<BlocEvent, BlocState, BlocSR> {
  // 构造函数和其他方法
}

2. 创建状态类

扩展你的状态类以处理不同的状态:

class _ExampleScreenState extends BaseState<BlocState, ExampleScreenBloc, BlocSR, ExampleScreen> {
  // 构造函数和其他方法
}

3. 创建BLoC实例

createBloc函数中创建BLoC实例:

ExampleScreenBloc createBloc() => ExampleScreenBloc();

4. 编写小部件主体

buildWidget方法中编写你的小部件主体,而不是在build方法中:

[@override](/user/override)
Widget buildWidget(BuildContext context) {
  return Scaffold(
    appBar: AppBar(
      title: Text('Example Screen'),
    ),
    body: Center(
      child: Text('Hello, World!'),
    ),
  );
}

5. 处理Single Result事件或状态

可以使用集成的小部件来处理Single Result事件或状态:

srObserver(
  context: context,
  onSR: (BuildContext context, BlocSR sr) {
    // 处理Single Result
  },
  child: Scaffold(
    appBar: AppBar(
      title: Text('Example Screen'),
    ),
    body: Center(
      child: Text('Hello, World!'),
    ),
  ),
);

或者你可以重写onSR方法:

[@override](/user/override)
void onSR(BuildContext context, ExampleScreenBloc bloc, BlocSR sr) {
  // 处理Single Result
}

6. 处理失败对象

重写onFailure方法来处理失败对象:

[@override](/user/override)
void onFailure(BuildContext context, ExampleScreenBloc bloc, Failure failure) {
  // 处理失败
}

7. 实现自定义进度状态行为

重写onProgress方法来实现自定义进度状态行为:

[@override](/user/override)
void onProgress(BuildContext context, ExampleScreenBloc bloc, BaseProgressState progress) {
  // 处理进度状态
}

使用BLoC小部件

1. blocBuilder方法

blocBuilder方法用于根据新的状态创建小部件:

blocBuilder(
  builder: (BuildContext context, BlocState state) => MyWidget(...),
);

2. blocListener方法

blocListener方法用于响应BLoC状态的变化:

blocListener(
  listener: (context, state) => print(state),
  listenWhen: (prev, curr) => prev != curr,
  child: MyWidget(...),
);

3. blocConsumer方法

blocConsumer方法同时暴露了构建器和监听器,以便对新状态做出反应:

blocConsumer(
  listener: (context, state) => print(state),
  builder: (context, state) => MyWidget(...),
  listenWhen: (prev, curr) => prev != curr,
  buildWhen: (prev, curr) => prev != curr,
);

你也可以直接使用flutter_bloc包中的BlocBuilderBlocListenerBlocConsumer小部件,没有任何限制。

完整示例

以下是一个完整的示例,展示了如何使用onix_flutter_bloc插件:

import 'package:example/base_bloc_example/base_bloc_example_screen.dart';
import 'package:example/base_cubit_example/base_cubit_example_screen.dart';
import 'package:example/di.dart';
import 'package:flutter/material.dart';
import 'package:get_it/get_it.dart';
import 'package:loader_overlay/loader_overlay.dart';

void main() {
  WidgetsFlutterBinding.ensureInitialized();
  initializeDi(GetIt.I);
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  [@override](/user/override)
  Widget build(BuildContext context) {
    return GlobalLoaderOverlay(
      child: MaterialApp(
        theme: ThemeData(
          colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
          useMaterial3: true,
        ),
        initialRoute: '/',
        routes: {
          '/': (context) => const MyHomePage(),
          '/base_cubit_example': (context) => const BaseCubitExampleScreen(title: 'Base Cubit Example'),
          '/base_bloc_example': (context) => const BaseBlocExampleScreen(title: 'Base BLoC Example'),
        },
      ),
    );
  }
}

class MyHomePage extends StatelessWidget {
  const MyHomePage({super.key});

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Theme.of(context).colorScheme.inversePrimary,
        title: const Text('Onix Flutter Core Examples'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            ElevatedButton(
              onPressed: () => Navigator.pushNamed(context, '/base_cubit_example'),
              child: const Text('Base Cubit'),
            ),
            const SizedBox(height: 16),
            ElevatedButton(
              onPressed: () => Navigator.pushNamed(context, '/base_bloc_example'),
              child: const Text('Base BLoC'),
            ),
          ],
        ),
      ),
    );
  }
}

更多关于Flutter状态管理插件onix_flutter_bloc的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter状态管理插件onix_flutter_bloc的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,下面是一个关于如何使用 onix_flutter_bloc 进行状态管理的 Flutter 代码示例。onix_flutter_bloc 是一个 Flutter 状态管理库,类似于 flutter_bloc,但可能具有不同的特性和实现。由于 onix_flutter_bloc 并不是一个广为人知的库(至少在我最后的知识更新时),这里的示例将基于一般的 Bloc 状态管理概念,并假设 onix_flutter_bloc 有类似的使用方式。如果 onix_flutter_bloc 有特定的 API 或使用方法,请参考其官方文档进行调整。

首先,你需要定义你的状态(States)和事件(Events)。

// counter_state.dart
import 'package:equatable/equatable.dart';

abstract class CounterState extends Equatable {
  const CounterState();

  @override
  List<Object> get props => [];
}

class CounterInitial extends CounterState {}

class CounterIncremented extends CounterState {
  final int count;

  const CounterIncremented({required this.count});

  @override
  List<Object> get props => [count];
}
// counter_event.dart
import 'package:equatable/equatable.dart';

abstract class CounterEvent extends Equatable {
  const CounterEvent();

  @override
  List<Object> get props => [];
}

class IncrementEvent extends CounterEvent {}

接下来,你需要创建一个 Bloc 来处理这些事件并生成新的状态。

// counter_bloc.dart
import 'package:bloc/bloc.dart';
import 'counter_event.dart';
import 'counter_state.dart';

class CounterBloc extends Bloc<CounterEvent, CounterState> {
  CounterBloc() : super(CounterInitial());

  @override
  Stream<CounterState> mapEventToState(CounterEvent event) async* {
    if (event is IncrementEvent) {
      yield* _mapIncrementEventToState();
    }
  }

  Stream<CounterState> _mapIncrementEventToState() async* {
    final currentState = state;
    if (currentState is CounterInitial) {
      yield CounterIncremented(count: 1);
    } else if (currentState is CounterIncremented) {
      yield CounterIncremented(count: currentState.count + 1);
    }
  }
}

现在,在你的 Flutter 应用中使用这个 Bloc。

// main.dart
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'counter_bloc.dart';
import 'counter_event.dart';
import 'counter_state.dart';

void main() {
  runApp(BlocProvider<CounterBloc>(
    create: (_) => CounterBloc(),
    child: MyApp(),
  ));
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: Text('Counter App')),
        body: Center(
          child: CounterPage(),
        ),
        floatingActionButton: FloatingActionButton(
          onPressed: () => context.read<CounterBloc>().add(IncrementEvent()),
          tooltip: 'Increment',
          child: Icon(Icons.add),
        ),
      ),
    );
  }
}

class CounterPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return BlocBuilder<CounterBloc, CounterState>(
      builder: (context, state) {
        if (state is CounterInitial) {
          return Text('You have pushed the button this many times:');
        }
        if (state is CounterIncremented) {
          return Text(
            'You have pushed the button this many times: ${state.count}',
            style: Theme.of(context).textTheme.headline4,
          );
        }
        return Container();
      },
    );
  }
}

请注意,上述代码使用了 flutter_bloc 库而不是 onix_flutter_bloc。如果 onix_flutter_bloc 的使用方式类似,你可以根据上述模式进行调整。如果 onix_flutter_bloc 有特定的 API 或不同的使用方法,请参考其官方文档。

如果你确实在使用 onix_flutter_bloc,并且它有不同于 flutter_bloc 的 API,请提供具体的文档或信息,以便我能给出更准确的示例。

回到顶部