Flutter架构插件q_architecture的使用

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

Flutter架构插件q_architecture的使用

q_architecture 是一套可重用的类,旨在加快开发时间并减少不必要的样板代码。它由 riverpod 提供支持。

快速入门

1. 创建抽象仓库并实现它

首先,我们需要创建一个抽象仓库接口,并提供其实现。

import 'package:either_dart/either.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';

// 定义一个仓库提供者
final repositoryProvider = Provider<YourRepository>(
      (_) => YourRepositoryImplementation(),
);

// 抽象仓库接口
abstract class YourRepository {
  Either<Failure, String> getYourString();
}

// 实现仓库
class YourRepositoryImplementation implements YourRepository {
  [@override](/user/override)
  Future<Either<Failure, String>> getYourString() async {
    await Future.delayed(const Duration(seconds: 3));
    if (Random().nextBool()) {
      return Right('Your string');
    } else {
      return Left(Failure.generic());
    }
  }
}

2. 创建 Notifier 并调用仓库方法

接下来,我们创建一个继承自 BaseNotifier 的 notifier,并添加调用仓库方法的方法。

import 'package:flutter_riverpod/flutter_riverpod.dart';

class YourNotifier extends BaseNotifier<String> {
  late YourRepository _yourRepository;

  YourNotifier(this._yourRepository, super.ref);

  [@override](/user/override)
  void prepareForBuild() {
    _yourRepository = ref.watch(repositoryProvider);
  }

  Future<void> getYourString() =>
      execute(
        _yourRepository.getYourString(),
        withLoadingState: true,
        globalLoading: false,
        globalFailure: false,
      );
}

3. 创建 Notifier 的 Provider

final yourNotifierProvider = NotifierProvider<YourNotifier, BaseState<String>>(
  () => YourNotifier(YourRepositoryImplementation(), null),
);

4. 在 Widget 中调用 Notifier 方法并监听变化

在你的 widget 中,通过 provider 调用 notifier 的方法,并监听状态变化。

import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';

class YourPage extends ConsumerWidget {
  const YourPage({Key? key}) : super(key: key);

  [@override](/user/override)
  Widget build(BuildContext context, WidgetRef ref) {
    final state = ref.watch(yourNotifierProvider);
    return Scaffold(
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Text(
              switch (state) {
                Data(data: final sentence) => sentence,
                Loading() => 'Loading',
                Initial() => 'Initial',
                Error(failure: final failure) => failure.toString(),
              },
            ),
            TextButton(
              onPressed: () => ref.read(yourNotifierProvider.notifier).getYourString(),
              child: const Text('Get string'),
            ),
          ],
        ),
      ),
    );
  }
}

示例 Demo

以下是一个完整的示例 demo,展示了如何使用 q_architecture 插件。

1. 创建项目和依赖

首先,确保你已经在 pubspec.yaml 文件中添加了 q_architecture 和其他必要的依赖。

dependencies:
  flutter:
    sdk: flutter
  riverpod: ^1.0.0
  either_dart: ^0.6.0
  equatable: ^2.0.3
  # 添加 q_architecture 依赖
  q_architecture: ^x.x.x

运行 flutter pub get 来安装这些依赖。

2. 创建 Repository 和 Notifier

// repository.dart
import 'package:either_dart/either.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';

final exampleRepositoryProvider = Provider<ExampleRepository>(
  (_) => ExampleRepositoryImpl(),
);

abstract class ExampleRepository {
  Future<Either<Failure, String>> getSomeString();
}

class ExampleRepositoryImpl implements ExampleRepository {
  [@override](/user/override)
  Future<Either<Failure, String>> getSomeString() async {
    await Future.delayed(const Duration(seconds: 3));
    if (Random().nextBool()) {
      return Right('Your string');
    } else {
      return Left(Failure.generic());
    }
  }
}
// notifier.dart
import 'package:flutter_riverpod/flutter_riverpod.dart';

final exampleNotifierProvider = NotifierProvider<ExampleNotifier, BaseState<String>>(
  () => ExampleNotifier(),
);

class ExampleNotifier extends BaseNotifier<String> {
  late ExampleRepository _exampleRepository;

  ExampleNotifier() {
    _exampleRepository = ref.read(exampleRepositoryProvider);
  }

  [@override](/user/override)
  void prepareForBuild() {
    _exampleRepository = ref.watch(exampleRepositoryProvider);
  }

  Future<void> getSomeStringFullExample() =>
      execute(
        _exampleRepository.getSomeString(),
        withLoadingState: true,
        globalLoading: false,
        globalFailure: true,
      );
}

3. 创建 UI 页面

// main.dart
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'notifier.dart';
import 'repository.dart';

void main() {
  runApp(ProviderScope(child: MyApp()));
}

class MyApp extends StatelessWidget {
  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Q Architecture Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: ExamplePage(),
    );
  }
}

class ExamplePage extends ConsumerWidget {
  [@override](/user/override)
  Widget build(BuildContext context, WidgetRef ref) {
    final state = ref.watch(exampleNotifierProvider);
    return Scaffold(
      appBar: AppBar(
        title: Text('Q Architecture Demo'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Text(
              switch (state) {
                Data(data: final sentence) => sentence,
                Loading() => 'Loading',
                Initial() => 'Initial',
                Error(failure: final failure) => failure.toString(),
              },
            ),
            ElevatedButton(
              onPressed: () => ref.read(exampleNotifierProvider.notifier).getSomeStringFullExample(),
              child: Text('Get String'),
            ),
          ],
        ),
      ),
    );
  }
}

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

1 回复

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


当然,以下是一个关于如何在Flutter项目中使用q_architecture插件的代码示例。q_architecture是一个用于Flutter应用的架构插件,它基于Clean Architecture原则设计,有助于组织和管理应用的结构。

1. 添加依赖

首先,你需要在pubspec.yaml文件中添加q_architecture的依赖:

dependencies:
  flutter:
    sdk: flutter
  q_architecture: ^最新版本号  # 请替换为实际可用的最新版本号

2. 创建项目结构

q_architecture建议按照以下结构组织项目:

your_flutter_app/
│
├── lib/
│   ├── core/
│   │   ├── domain/
│   │   ├── data/
│   │   ├── presentation/
│   │   └── usecases/
│   ├── features/
│   │   ├── feature_name/
│   │   │   ├── domain/
│   │   │   ├── data/
│   │   │   ├── presentation/
│   │   │   └── usecases/
│   └── app/
│       ├── main.dart
│       ├── router/
│       └── viewmodels/
│
└── ...

3. 实现示例

以下是一个简单的示例,演示如何使用q_architecture来管理用户登录功能。

3.1 定义Domain Layer

core/domain中定义一个简单的User实体和UseCase:

// core/domain/entities/user.dart
class User {
  final String id;
  final String name;

  User({required this.id, required this.name});
}

// core/domain/usecases/login_usecase.dart
import 'package:dartz/dartz.dart';
import 'package:q_architecture/q_architecture.dart';

class LoginUseCase extends UseCase<User, String, NoParams> {
  @override
  Future<Either<Failure, User>> execute(NoParams params) async {
    // 模拟登录逻辑
    return Right(User(id: '1', name: 'John Doe'));
  }
}

3.2 实现Data Layer

core/data中实现一个简单的数据源(Repository):

// core/data/repositories/user_repository.dart
import 'package:dartz/dartz.dart';
import '../../domain/entities/user.dart';
import '../../domain/usecases/login_usecase.dart';

class UserRepository {
  // 示例数据源方法,这里可以替换为实际的API调用或数据库查询
  Future<Either<String, User>> login(String credentials) async {
    // 模拟成功登录
    return Right(User(id: '1', name: 'John Doe'));
  }
}

3.3 创建Presentation Layer

features/login/presentation/viewmodels中创建一个ViewModel:

// features/login/presentation/viewmodels/login_viewmodel.dart
import 'package:dartz/dartz.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:q_architecture/q_architecture.dart';
import '../../domain/entities/user.dart';
import '../../domain/usecases/login_usecase.dart';

final loginViewModelProvider = Provider<LoginViewModel>((ref) {
  final loginUseCase = ref.watch(loginUseCaseProvider);
  return LoginViewModel(loginUseCase);
});

class LoginViewModel extends ViewModel {
  final LoginUseCase loginUseCase;

  LoginViewModel(this.loginUseCase);

  Future<void> login(String credentials) async {
    final result = await loginUseCase.execute(NoParams());
    result.fold(
      (failure) => handleFailure(failure),
      (user) => handleSuccess(user),
    );
  }

  void handleSuccess(User user) {
    // 处理成功逻辑,例如更新UI
    print('Login successful: ${user.name}');
  }

  void handleFailure(Failure failure) {
    // 处理失败逻辑,例如显示错误消息
    print('Login failed: ${failure.message}');
  }
}

3.4 创建UI Layer

features/login/presentation/widgets中创建一个简单的登录界面:

// features/login/presentation/widgets/login_screen.dart
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:your_flutter_app/features/login/presentation/viewmodels/login_viewmodel.dart';

class LoginScreen extends ConsumerWidget {
  @override
  Widget build(BuildContext context, WidgetRef ref) {
    final loginViewModel = ref.watch(loginViewModelProvider);

    return Scaffold(
      appBar: AppBar(title: Text('Login')),
      body: Padding(
        padding: const EdgeInsets.all(16.0),
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            TextField(
              decoration: InputDecoration(labelText: 'Credentials'),
              onSubmitted: (credentials) {
                loginViewModel.login(credentials);
              },
            ),
            SizedBox(height: 16),
            ElevatedButton(
              onPressed: () {
                // 假设有一个TextField的controller,这里用onSubmitted作为示例
              },
              child: Text('Login'),
            ),
          ],
        ),
      ),
    );
  }
}

3.5 更新Main入口

最后,在app/main.dart中配置并启动应用:

// app/main.dart
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'router/router.dart';

void main() {
  runApp(
    ProviderContainer(
      initialDependencies: Dependencies(),
      child: MaterialApp(
        title: 'Flutter App',
        theme: ThemeData(
          primarySwatch: Colors.blue,
        ),
        initialRoute: '/',
        onGenerateRoute: Router.generateRoute,
      ),
    ),
  );
}

总结

以上代码展示了如何在Flutter项目中使用q_architecture插件来组织和管理应用结构。通过分层设计,我们可以更好地分离关注点,提高代码的可维护性和可扩展性。请根据实际需求调整和完善代码。

回到顶部