Flutter架构插件q_architecture的使用
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
更多关于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
插件来组织和管理应用结构。通过分层设计,我们可以更好地分离关注点,提高代码的可维护性和可扩展性。请根据实际需求调整和完善代码。