Flutter架构搭建插件clean_architecture_scaffold的使用

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

Flutter架构搭建插件clean_architecture_scaffold的使用

轻松地在你的Flutter项目中基于Clean Architecture搭建文件夹结构。通过此插件,你可以减少样板代码并确保不同功能或模块之间的一致性目录结构。

特点

  • 自动生成符合Clean Architecture标准的文件夹结构。
  • 减少手动创建文件夹的重复任务。
  • 确保不同功能或模块之间的一致性。

安装

在你的pubspec.yaml文件中添加该插件:

dependencies:
  clean_architecture_scaffold: ^0.0.7

使用

安装完成后,使用以下命令来为你的功能生成文件夹结构:

dart run clean_architecture_scaffold:main -f FEATURE_NAME

这将减少样板代码,并确保你已设置正确的目录结构以实现Clean Architecture的功能。

贡献

我们欢迎对clean_architecture_scaffold的贡献!如果你有任何功能建议、错误报告或想贡献代码:

  1. 查看我们的仓库:clean_architecture_scaffold
  2. 创建一个新的拉取请求或打开一个issue。

感谢你支持并使用clean_architecture_scaffold


示例代码

以下是使用该插件的基本示例代码:

import 'package:flutter/material.dart';

void main() {
  runApp(const MyApp());
}

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

  // 这个小部件是你的应用的根。
  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        // 这是你的应用的主题。
        //
        // 尝试:运行你的应用,你会看到应用有一个蓝色工具栏。然后,不退出应用,
        // 尝试将颜色方案中的seedColor改为Colors.green
        // 并触发热重载(保存更改或按热重载按钮)。 
        //
        // 注意:计数器不会重置为零;应用状态不会在重载时丢失。要重置状态,请使用热重启。
        //
        // 这也适用于代码,而不仅仅是值:大多数代码更改可以通过热重载来测试。
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
        useMaterial3: true,
      ),
      home: const MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key, required this.title});

  // 这个小部件是你的应用的主页。它是有状态的,意味着它有一个状态对象(定义在下面)包含影响其外观的字段。
  // 
  // 这个类是状态的配置。它持有由父组件(在这个例子中是App小部件)提供的值(在这个例子中是标题),并用于状态的构建方法。
  // 在Widget子类中,字段总是标记为"final"。

  final String title;

  [@override](/user/override)
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  int _counter = 0;

  void _incrementCounter() {
    setState(() {
      // 这次调用setState告诉Flutter框架某些事情已经改变,因此它会重新运行下面的构建方法
      // 以便显示更新后的值。如果我们不调用setState()改变_counter,那么构建方法将不会被调用,
      // 因此什么也不会发生。
      _counter++;
    });
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    // 每次调用setState时,此方法都会重新运行,例如上面的_incrementCounter方法。
    //
    // Flutter框架经过优化,使得重新运行构建方法非常快,因此你可以只需重建需要更新的小部件,
    // 而不必单独更改实例。
    return Scaffold(
      appBar: AppBar(
        // 尝试:尝试在这里更改颜色到特定颜色(例如Colors.amber),并触发热重载以查看AppBar
        // 颜色变化,而其他颜色保持不变。
        backgroundColor: Theme.of(context).colorScheme.inversePrimary,
        // 这里我们从App.build方法创建的MyHomePage对象中获取值,
        // 并将其用于设置我们的appbar标题。
        title: Text(widget.title),
      ),
      body: Center(
        // Center是一个布局小部件。它接受一个子元素并将它定位在父元素的中间。
        child: Column(
          // Column也是一个布局小部件。它接受一个子元素列表并垂直排列它们。
          // 默认情况下,它水平调整自身大小以适应其子元素,并尝试与父元素一样高。
          //
          // Column有许多属性可以控制它如何调整自身大小以及如何放置其子元素。
          // 在这里,我们使用mainAxisAlignment来垂直居中子元素;
          // 主轴是垂直方向,因为Columns是垂直的(交叉轴是水平方向)。
          //
          // 尝试:触发调试绘制(选择IDE中的“切换调试绘制”操作,或在控制台中按“p”键),
          // 以查看每个小部件的线框图。
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            const Text(
              '你已经按了按钮这么多次:',
            ),
            Text(
              '$_counter',
              style: Theme.of(context).textTheme.headlineMedium,
            ),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _incrementCounter,
        tooltip: 'Increment',
        child: const Icon(Icons.add),
      ), // 这个逗号使自动格式化更美观。
    );
  }
}

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

1 回复

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


当然,下面是一个关于如何在Flutter项目中使用clean_architecture_scaffold插件来搭建Clean Architecture架构的示例代码。clean_architecture_scaffold插件可以帮助你快速启动一个遵循Clean Architecture原则的项目结构。

首先,确保你已经在你的pubspec.yaml文件中添加了clean_architecture_scaffold依赖:

dependencies:
  flutter:
    sdk: flutter
  clean_architecture_scaffold: ^最新版本号  # 替换为实际的最新版本号

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

安装完成后,你可以使用以下步骤和代码来搭建你的项目架构。

1. 创建项目并使用Scaffold生成基础结构

假设你已经创建了一个Flutter项目,现在你可以使用clean_architecture_scaffold来生成基础的项目结构。虽然这个插件可能不直接提供一个命令行工具来生成结构(这取决于插件的具体实现),但我们可以手动模拟这个过程,并展示一个典型的Clean Architecture结构。

2. 项目结构示例

一个典型的Clean Architecture项目结构可能如下所示:

my_flutter_app/
├── lib/
│   ├── data/           # 数据访问层
│   │   ├── repositories/
│   │   └── datasources/
│   ├── domain/         # 业务逻辑层
│   │   ├── models/
│   │   ├── usecases/
│   │   └── repositories/
│   ├── presentation/   # 表示层
│   │   ├── screens/
│   │   └── widgets/
│   ├── core/           # 核心层,包含依赖注入、错误处理等
│   │   ├── di/
│   │   └── errors/
│   └── main.dart       # 应用的入口
├── pubspec.yaml
└── ...

3. 示例代码

下面是一个简化的示例,展示如何使用这个结构创建一个简单的用户列表显示功能。

main.dart

import 'package:flutter/material.dart';
import 'presentation/screens/user_list_screen.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Clean Architecture Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: UserListScreen(),
    );
  }
}

presentation/screens/user_list_screen.dart

import 'package:flutter/material.dart';
import '../widgets/user_list.dart';

class UserListScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('User List'),
      ),
      body: UserList(),
    );
  }
}

presentation/widgets/user_list.dart

import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import '../../domain/usecases/get_users.dart';
import '../../core/models/user_model.dart';

class UserList extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final getUsers = Provider.of<GetUsers>(context);

    return FutureBuilder<List<User>>(
      future: getUsers.execute(),
      builder: (context, snapshot) {
        if (snapshot.connectionState == ConnectionState.waiting) {
          return CircularProgressIndicator();
        } else if (snapshot.hasError) {
          return Text('Error: ${snapshot.error}');
        } else if (snapshot.hasData) {
          return ListView.builder(
            itemCount: snapshot.data!.length,
            itemBuilder: (context, index) {
              return ListTile(
                title: Text(snapshot.data![index].name),
              );
            },
          );
        } else {
          return Container();
        }
      },
    );
  }
}

domain/usecases/get_users.dart

import 'dart:async';
import '../../data/repositories/user_repository.dart';
import '../../core/models/user_model.dart';

class GetUsers {
  final UserRepository userRepository;

  GetUsers(this.userRepository);

  Future<List<User>> execute() async {
    return await userRepository.getUsers();
  }
}

data/repositories/user_repository.dart

import 'dart:async';
import '../datasources/user_datasource.dart';
import '../../core/models/user_model.dart';

class UserRepository {
  final UserDatasource userDatasource;

  UserRepository(this.userDatasource);

  Future<List<User>> getUsers() async {
    // 模拟从数据源获取用户列表
    return await userDatasource.getUsers();
  }
}

data/datasources/user_datasource.dart

import 'dart:async';
import '../../core/models/user_model.dart';

abstract class UserDatasource {
  Future<List<User>> getUsers();
}

class UserDatasourceImpl implements UserDatasource {
  @override
  Future<List<User>> getUsers() async {
    // 这里可以是从API获取数据,为了简单起见,返回硬编码数据
    return [
      User(id: 1, name: 'Alice'),
      User(id: 2, name: 'Bob'),
    ];
  }
}

core/models/user_model.dart

class User {
  final int id;
  final String name;

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

4. 依赖注入

在更复杂的应用中,你可能会使用依赖注入库(如get_itprovider)来管理依赖关系。上面的示例中,为了简单起见,没有展示依赖注入的具体实现,但在实际项目中,你应该考虑如何管理和注入依赖。

这个示例提供了一个基本的Clean Architecture框架,你可以根据实际需求进行扩展和修改。希望这对你有所帮助!

回到顶部