Flutter通用业务逻辑处理插件generic_bloc的使用

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

Flutter通用业务逻辑处理插件generic_bloc的使用

generic_bloc 是一个用于管理业务逻辑的插件,它可以帮助你更好地处理数据的状态,比如加载状态、部分加载状态和完全加载状态。该插件包括 GenericBloc 用于列表数据,GenericOneBloc 用于单个值。

示例用法 GenericOneBloc

在Bloc中定义

final GenericOneBloc<bool> activeBanner = GenericOneBloc<bool>();

在UI中使用

return BlocBuilder<GenericOneBloc<bool>, GenericOneState<bool>>(
  bloc: context.read<SomeBloc>().dayDelivery,
  builder: (context, state) => state.map(
    loadingState: (state) => const Skeleton(), // 显示加载状态
    loadedState: (state) => SomeWidget(
      isActive: state.data,
    ), // 显示已加载的数据
    errorState: (state) => const Text(state.exception), // 显示错误信息
  ),
);

示例用法 GenericBloc

在Bloc中定义

final GenericBloc<Product> products = GenericBloc<Product>();

在UI中使用

BlocBuilder<GenericBloc<Product>, GenericState<Product>>(
  bloc: context.read<SomeBloc>().products,
  builder: (context, state) => state.map(
    loadingState: (loadingState) => Skeleton(), // 显示加载状态
    loadedState: (loadedState) => Column(
      children: [
        ...loadedState.data.map((e) => Widget(e)), // 显示部分加载的数据
        Skeleton(),
      ],
    ),
    fullLoadedState: (fullLoadedState) => Column(
      children: fullLoadedState.data.map(
        (e) => Widget(e),
      ),
    ), // 显示完全加载的数据
    errorState: (errorState) => Text(errorState.exception), // 显示错误信息
  ),
)

如何发送事件

对于 GenericBloc

someGenericBloc.add(GenericEvent.showLoading()); // 显示加载状态
someGenericBloc.add(GenericEvent.showLoaded(data: someData)); // 显示部分加载的数据
someGenericBloc.add(GenericEvent.showFullLoaded(data: someData)); // 显示完全加载的数据
someGenericBloc.add(GenericEvent.showError(exception: 'error')); // 显示错误信息

对于 GenericOneBloc

someGenericBloc.add(GenericOneEvent.showLoading()); // 显示加载状态
someGenericBloc.add(GenericOneEvent.showLoaded(data: someData)); // 显示已加载的数据
someGenericBloc.add(GenericOneEvent.showError(exception: 'error')); // 显示错误信息

更多关于Flutter通用业务逻辑处理插件generic_bloc的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter通用业务逻辑处理插件generic_bloc的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,下面是一个关于如何在Flutter中使用generic_bloc插件来处理通用业务逻辑的示例代码。这个插件可以帮助你创建可重用的BLoC(Business Logic Component)来处理应用中的常见逻辑。

首先,你需要确保你的Flutter项目已经包含了generic_bloc依赖。在你的pubspec.yaml文件中添加以下依赖:

dependencies:
  flutter:
    sdk: flutter
  generic_bloc: ^x.y.z  # 请替换为最新的版本号

然后运行flutter pub get来安装依赖。

接下来,我们将创建一个简单的示例,展示如何使用generic_bloc来处理一个登录场景。

1. 定义Event和State

首先,我们需要定义事件(Event)和状态(State)。事件是用户触发的动作,而状态是应用对这些事件的响应。

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

abstract class LoginEvent extends Equatable {
  const LoginEvent();

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

class LoginButtonPressed extends LoginEvent {
  final String username;
  final String password;

  const LoginButtonPressed({required this.username, required this.password});

  @override
  List<Object?> get props => [username, password];
}
// states.dart
import 'package:equatable/equatable.dart';

abstract class LoginState extends Equatable {
  const LoginState();

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

class LoginInitial extends LoginState {
  const LoginInitial();
}

class LoginLoading extends LoginState {
  const LoginLoading();
}

class LoginSuccess extends LoginState {
  const LoginSuccess();
}

class LoginFailure extends LoginState {
  final String message;

  const LoginFailure({required this.message});

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

2. 创建BLoC

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

// login_bloc.dart
import 'dart:async';
import 'package:bloc/bloc.dart';
import 'package:generic_bloc/generic_bloc.dart';
import 'events.dart';
import 'states.dart';

class LoginBloc extends Bloc<LoginEvent, LoginState> {
  LoginBloc() : super(LoginInitial()) {
    on<LoginButtonPressed>((event, emit) async {
      emit(LoginLoading());
      try {
        // 模拟一个网络请求
        await Future.delayed(const Duration(seconds: 2));
        emit(LoginSuccess());
      } catch (_) {
        emit(LoginFailure(message: 'Login failed'));
      }
    });
  }
}

3. 在UI中使用BLoC

最后,我们需要在UI中使用这个BLoC来显示不同的状态。

// login_page.dart
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'login_bloc.dart';
import 'states.dart';

class LoginPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Login')),
      body: Padding(
        padding: const EdgeInsets.all(16.0),
        child: BlocConsumer<LoginBloc, LoginState>(
          listener: (context, state) {},
          builder: (context, state) {
            if (state is LoginLoading) {
              return CircularProgressIndicator();
            } else if (state is LoginSuccess) {
              return Text('Login Successful');
            } else if (state is LoginFailure) {
              return Text('Error: ${state.message}');
            } else {
              return Column(
                children: <Widget>[
                  TextField(
                    decoration: InputDecoration(labelText: 'Username'),
                    onChanged: (value) {
                      context.read<LoginBloc>().add(
                        LoginButtonPressed(
                          username: value,
                          password: context.watch<LoginBloc>().state is LoginInitial
                              ? ''
                              : _passwordController.text,
                        ),
                      );
                    },
                  ),
                  TextField(
                    decoration: InputDecoration(labelText: 'Password'),
                    obscureText: true,
                    controller: _passwordController,
                  ),
                  SizedBox(height: 20),
                  ElevatedButton(
                    onPressed: () {
                      final username = context.watch<LoginBloc>().state is LoginInitial
                          ? _usernameController.text
                          : '';
                      if (username.isNotEmpty && _passwordController.text.isNotEmpty) {
                        context.read<LoginBloc>().add(
                          LoginButtonPressed(
                            username: username,
                            password: _passwordController.text,
                          ),
                        );
                      }
                    },
                    child: Text('Login'),
                  ),
                ],
              );
            }
          },
        ),
      ),
    );
  }

  final _passwordController = TextEditingController();
  // Note: For simplicity, _usernameController is omitted here but you should add it similarly.
}

4. 在应用中注册BLoC

确保在你的应用入口文件(通常是main.dart)中注册BLoC提供者。

// main.dart
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'login_page.dart';
import 'login_bloc.dart';

void main() {
  runApp(
    BlocProvider<LoginBloc>(
      create: (context) => LoginBloc(),
      child: MaterialApp(
        home: LoginPage(),
      ),
    ),
  );
}

这个示例展示了如何使用generic_bloc插件(尽管在这个例子中我们并没有直接使用到generic_bloc提供的特定功能,因为这是一个简单的场景,但你可以根据需求扩展以利用它的泛型特性)来处理登录逻辑。在实际项目中,你可以根据需求扩展事件和状态,以及BLoC中的业务逻辑。

回到顶部