Flutter封装模板及最佳实践

发布于:2025-07-31 ⋅ 阅读:(22) ⋅ 点赞:(0)

以下是一个完整且全面的Flutter封装模板,包含统一标题栏、状态管理、网络请求、路由管理等核心模块,采用分层架构设计:


项目结构

lib/
├── core/
│   ├── base/
│   │   ├── base_controller.dart   // 状态管理基类
│   │   ├── base_view.dart         // 页面基类
│   │   └── base_model.dart        // 数据模型基类
│   ├── utils/
│   │   ├── screen_util.dart       // 屏幕适配
│   │   ├── log_util.dart          // 日志工具
│   │   └── storage_util.dart      // 本地存储
│   ├── network/
│   │   ├── dio_client.dart        // Dio封装
│   │   ├── api_exception.dart     // 异常处理
│   │   └── api_response.dart      // 统一响应体
│   └── theme/
│       ├── app_colors.dart        // 颜色常量
│       ├── app_text_style.dart    // 文字样式
│       └── app_theme.dart         // 主题配置
├── common/
│   ├── widgets/
│   │   ├── app_bar.dart           // 统一标题栏
│   │   ├── loading.dart           // 加载组件
│   │   └── empty_view.dart        // 空视图
│   └── values/
│       └── strings.dart           // 多语言
├── modules/                       // 业务模块
└── main.dart

核心模块实现

1. 统一标题栏 (common/widgets/app_bar.dart)
class CustomAppBar extends AppBar {
   
   
  CustomAppBar({
   
   
    String title = "",
    bool showBack = true,
    List<Widget>? actions,
  }) : super(
          title: Text(title, style: AppTextStyle.title),
          centerTitle: true,
          elevation: 0,
          backgroundColor: AppColors.primary,
          automaticallyImplyLeading: showBack,
          leading: showBack ? const BackButton(color: Colors.white) : null,
          actions: actions,
        );
}
2. 状态管理基类 (core/base/base_controller.dart)
import 'package:get/get.dart';

abstract class BaseController extends GetxController {
   
   
  final isLoading = false.obs;
  final errorMessage = ''.obs;

  void setLoading(bool value) => isLoading.value = value;
  
  void handleError(dynamic error) {
   
   
    errorMessage.value = error.toString();
    setLoading(false);
  }

  
  void onClose() {
   
   
    isLoading.close();
    errorMessage.close();
    super.onClose();
  }
}
3. 页面基类 (core/base/base_view.dart)
abstract class BaseView<T extends BaseController> extends GetView<T> {
   
   
  const BaseView({
   
   Key? key}) : super(key: key);

  
  Widget build(BuildContext context) {
   
   
    return Scaffold(
      appBar: buildAppBar(),
      body: Obx(() {
   
   
        if (controller.isLoading.value) return const LoadingWidget();
        if (controller.errorMessage.isNotEmpty) {
   
   
          return ErrorView(message: controller.errorMessage.value);
        }
        return buildBody(context);
      }),
    );
  }

  PreferredSizeWidget? buildAppBar() => null;
  
  Widget buildBody(BuildContext context);
}
4. 网络请求封装 (core/network/dio_client.dart)
class DioClient {
   
   
  static final Dio _dio = Dio(BaseOptions(
    baseUrl: 'https://api.example.com',
    connectTimeout: 5000,
    receiveTimeout: 3000,
  ))
    ..interceptors.add(LogInterceptor())
    ..interceptors.add(InterceptorsWrapper(
      onError: (error, handler) {
   
   
        throw ApiException.fromDioError(error);
      },
    ));

  static Future<ApiResponse> get(String path, {
   
   Map<String, dynamic>? params}) async {
   
   
    try {
   
   
      final response = await _dio.get(path, queryParameters: params);
      return ApiResponse.success(response.data);
    } on ApiException catch (e) {
   
   
      return ApiResponse.failure(e.toString());
    }
  }

  // 其他请求方法...
}
5. 屏幕适配工具 (core/utils/screen_util.dart)
class ScreenUtil {
   
   
  static late double screenWidth;
  static late double screenHeight;

  static void init(BuildContext context) {
   
   
    final mediaQuery = MediaQuery.of(context);
    screenWidth = mediaQuery.size.width;
    screenHeight = mediaQuery.size.height;
  }

  static double scaleWidth(double size) => size * (screenWidth / 375);
}

使用示例

业务页面实现
class HomePage extends BaseView<HomeController> {
   
   
  const HomePage({
   
   Key? key}) :<

网站公告

今日签到

点亮在社区的每一天
去签到