Flutter UI交互插件ui_actionable_bloc的使用

Flutter UI交互插件ui_actionable_bloc的使用

ui_actionable_bloc 是一个基于 Bloc 的混入类,允许执行UI操作并接收结果。以下是使用该插件的详细步骤。

安装包

pubspec.yaml 文件中添加依赖:

dependencies:
  ui_actionable_bloc: ^0.0.3

然后运行 flutter pub get 更新依赖。

添加混入

在你的 Cubit 类中添加 UiActionableBlocMixin 混入:

class MyCubit extends Cubit<MyState>
    with UiActionableBlocMixin<MyState, MyAction> {
  MyCubit() : super(MyState());

  Future<void> onButtonPressed() async {
    const action = MyAction(['First', 'Second', 'Third']);
    final result = emitUiAction<String>(action);

    debugPrint('Cubit: $result');
  }
}

添加监听器

在你的UI中添加 BlocActionsListener 来监听动作:

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

  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      theme: ThemeData.dark(),
      home: BlocProvider(
        create: (context) => MyCubit(),
        child: Scaffold(
          appBar: AppBar(),
          body: Column(
            children: [
              const Center(
                child: Text('Hello World!'),
              ),
              MultiBlocListener(
                listeners: [
                  BlocActionsListener<MyCubit, MyState, MyAction>.completable(
                    listener: (context, state, action, completer) async {
                      final availableActions = action.options
                          .map(
                            (e) => CupertinoActionSheetAction(
                              onPressed: () {
                                Navigator.of(context).pop(e);
                              },
                              child: Text(e),
                            ),
                          )
                          .toList();

                      final result = await showModalBottomSheet(
                        context: context,
                        builder: (context) {
                          return CupertinoActionSheet(
                            title: const Text('Select'),
                            actions: availableActions,
                          );
                        },
                      );

                      completer(result);
                    },
                  ),
                ],
                child: Builder(
                  builder: (context) {
                    return ElevatedButton(
                      onPressed: context.read<MyCubit>().onButtonPressed,
                      child: const Text('Press me!'),
                    );
                  },
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

发射动作

在需要执行UI操作的地方调用 emitUiAction 方法:

Future<void> onButtonPressed() async {
  const action = MyAction(['First', 'Second', 'Third']);
  final result = emitUiAction<String>(action);

  debugPrint('Cubit: $result');
}

返回结果到Bloc

你可以通过 emitUiAction 返回结果。例如,在发送OTP后,弹出输入框请求用户输入OTP:

await _sendOtpUseCase();

// Otp will land here once the action is completed in a listener!
final otp = await emitUiAction<OtpAction.requestOtpInput>(user);

if (otp is! String) {
  /// User did not input the OTP.
  return;
}

await _validateOtpUseCase(otp);

你也可以使用 BlocActionsListener.completable 来处理更复杂的UI操作:

[@override](/user/override)
Widget build(BuildContext context) {
  return BlocActionsListener<MyCubit, MyState, MyAction>.completable(
    listener: (context, state, action, actionCompleter) {
      final otpInput = await Navigator.of(context).push(OtpInputRoute());

      // This will complete the emitUiAction future.
      actionCompleter(otpInput);
    },
    child: ...,
  );
}

更多关于Flutter UI交互插件ui_actionable_bloc的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter UI交互插件ui_actionable_bloc的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,以下是一个关于如何在Flutter项目中使用ui_actionable_bloc插件进行UI交互的代码示例。ui_actionable_bloc是一个有助于管理UI状态和事件的BLoC(Business Logic Component)库,尽管它不是Flutter官方库,但假设它提供了一些机制来简化UI状态管理和事件处理。

首先,你需要确保你的pubspec.yaml文件中已经添加了ui_actionable_bloc依赖(注意:实际库名和用法可能有所不同,这里假设库名为ui_actionable_bloc):

dependencies:
  flutter:
    sdk: flutter
  ui_actionable_bloc: ^latest_version  # 替换为实际版本号

然后,运行flutter pub get来获取依赖。

接下来,让我们创建一个简单的Flutter应用,展示如何使用ui_actionable_bloc来管理UI交互。

1. 定义状态和事件

首先,我们需要定义应用的状态和事件。

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

abstract class CounterEvent extends Equatable {
  const CounterEvent();

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

class IncrementEvent extends CounterEvent {}

class DecrementEvent extends CounterEvent {}
// states.dart
import 'package:equatable/equatable.dart';

class CounterState extends Equatable {
  final int count;

  const CounterState({required this.count});

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

  CounterState copyWith({int? count}) {
    return CounterState(count: count ?? this.count);
  }
}

2. 创建BLoC

接下来,我们创建一个BLoC来处理这些事件并生成状态。

// counter_bloc.dart
import 'dart:async';
import 'package:bloc/bloc.dart';
import 'package:ui_actionable_bloc/ui_actionable_bloc.dart';  // 假设库提供了一些便捷方法
import 'events.dart';
import 'states.dart';

class CounterBloc extends Bloc<CounterEvent, CounterState> with UiActionableBloc {
  CounterBloc() : super(CounterState(count: 0)) {
    on<IncrementEvent>((event, emit) => emit(state.copyWith(count: state.count + 1)));
    on<DecrementEvent>((event, emit) => emit(state.copyWith(count: state.count - 1)));
  }
}

3. UI层

现在,让我们在UI层使用这个BLoC。

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

void main() {
  runApp(MultiBlocProvider(
    providers: [
      BlocProvider<CounterBloc>(
        create: (context) => 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: BlocBuilder<CounterBloc, CounterState>(
            builder: (context, state) {
              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,
                  ),
                ],
              );
            },
          ),
        ),
        floatingActionButton: Column(
          mainAxisAlignment: MainAxisAlignment.end,
          crossAxisAlignment: CrossAxisAlignment.center,
          children: <Widget>[
            FloatingActionButton(
              onPressed: () => context.read<CounterBloc>().add(IncrementEvent()),
              tooltip: 'Increment',
              child: Icon(Icons.add),
            ),
            SizedBox(height: 10),
            FloatingActionButton(
              onPressed: () => context.read<CounterBloc>().add(DecrementEvent()),
              tooltip: 'Decrement',
              child: Icon(Icons.remove),
            ),
          ],
        ),
      ),
    );
  }
}

在这个示例中,我们创建了一个简单的计数器应用,使用ui_actionable_bloc(假设它提供了类似Bloc的功能)来管理UI状态和事件。CounterBloc处理IncrementEventDecrementEvent事件,并更新CounterState。UI层使用BlocBuilder监听状态变化,并在按钮点击时发送事件。

请注意,ui_actionable_bloc库可能并不真实存在,这里的代码示例是基于假设的。实际使用时,你需要根据具体的第三方库文档进行调整。如果ui_actionable_bloc库确实存在,请参考其官方文档获取准确的用法。

回到顶部