2025 从零开始Flutter getX 0基础教程(3)

这个示例完整展示了如何使用 GetX 构建一个功能完备的可复用页面,包括数据获取、表单处理、状态管理和页面导航等核心功能。

  1. 功能说明

    • 页面加载时自动获取用户数据
    • 表单提供实时验证
    • 点击更新按钮提交数据
    • 右上角按钮可导航到详情页

代码详解

1. 数据模型 (UserModel)
  • 定义用户数据结构,包含 idnameemailage 四个字段
  • 提供 fromJson 和 toJson 方法用于数据转换
  • 作用:标准化数据格式,方便数据传递和存储
2. 控制器 (UserProfileController)
  • 状态管理
    • user:存储当前用户数据,使用 Rx 使其可观察
    • isLoading:控制加载状态
    • errorMessage:存储错误信息
  • 表单管理
    • 为每个输入字段创建 TextEditingController
    • 提供表单验证方法,确保输入合法性
  • 业务逻辑
    • fetchUser:模拟从服务器获取用户数据
    • updateUser:模拟更新用户数据到服务器
    • navigateToDetailsPage:导航到详情页
  • 资源管理
    • 在控制器销毁时释放表单控制器资源
3. 用户资料页面 (UserProfilePage)
  • 依赖注入
    • 使用 Get.put() 初始化控制器,支持通过 tag 区分不同实例
  • 响应式 UI
    • 使用 Obx 包裹需要响应状态变化的部分
    • 根据 isLoadingerrorMessage 和 user 状态动态显示不同 UI
  • 表单交互
    • 将控制器的表单验证方法绑定到 TextFormField
    • 点击按钮时调用控制器的 updateUser 方法
4. 用户详情页面 (UserDetailsPage)
  • 获取控制器
    • 使用 Get.find() 获取已存在的控制器实例
  • 显示数据
    • 从控制器获取用户数据并显示

核心功能说明

  1. 状态管理

    • 使用 Rx 和 Obx 实现响应式编程,当状态变化时自动更新 UI
    • 无需手动管理 State,代码更简洁
  2. 依赖注入

    • GetX 提供的依赖注入系统简化了组件间的通信
    • 控制器可以在整个应用中共享和复用
  3. 导航管理

    • 使用 Get.to() 进行页面跳转
    • 无需使用 BuildContext,导航更简单
  4. 生命周期管理

    • 控制器自动管理生命周期,在需要时创建,不再使用时销毁
    • 通过 onClose() 方法释放资源,防止内存泄漏

使用方法

  1. 添加依赖

    yaml

    dependencies:
      get: ^4.6.5
    
  2. 集成到应用

    dart

    // 在路由中使用
    MaterialApp(
      home: UserProfilePage(userId: '123'),
    );
    

    import 'package:flutter/material.dart';
    import 'package:get/get.dart';
    
    // 数据模型 - 定义用户数据结构
    class UserModel {
      final String id;
      final String name;
      final String email;
      final int age;
    
      UserModel({
        required this.id,
        required this.name,
        required this.email,
        required this.age,
      });
    
      // 从 JSON 创建 UserModel
      factory UserModel.fromJson(Map<String, dynamic> json) {
        return UserModel(
          id: json['id'],
          name: json['name'],
          email: json['email'],
          age: json['age'],
        );
      }
    
      // 转换为 JSON
      Map<String, dynamic> toJson() {
        return {
          'id': id,
          'name': name,
          'email': email,
          'age': age,
        };
      }
    }
    
    // 控制器 - 处理业务逻辑和状态管理
    class UserProfileController extends GetxController {
      // 响应式状态 - 当值变化时自动更新 UI
      final Rx<UserModel?> user = Rx<UserModel?>(null);
      final RxBool isLoading = false.obs;
      final RxString errorMessage = ''.obs;
    
      // 表单控制器 - 管理输入框内容
      final TextEditingController nameController = TextEditingController();
      final TextEditingController emailController = TextEditingController();
      final TextEditingController ageController = TextEditingController();
    
      // 表单验证方法
      String? validateName(String? value) {
        if (value == null || value.isEmpty) {
          return '姓名不能为空';
        }
        return null;
      }
    
      String? validateEmail(String? value) {
        if (value == null || value.isEmpty) {
          return '邮箱不能为空';
        }
        if (!GetUtils.isEmail(value)) {
          return '无效的邮箱地址';
        }
        return null;
      }
    
      String? validateAge(String? value) {
        if (value == null || value.isEmpty) {
          return '年龄不能为空';
        }
        if (int.tryParse(value) == null) {
          return '年龄必须是数字';
        }
        return null;
      }
    
      // 获取用户数据 - 模拟 API 调用
      Future<void> fetchUser(String userId) async {
        isLoading.value = true;
        errorMessage.value = '';
    
        try {
          // 模拟网络延迟
          await Future.delayed(const Duration(seconds: 1));
    
          // 模拟 API 返回数据
          final mockUser = UserModel(
            id: userId,
            name: '张三',
            email: 'zhangsan@example.com',
            age: 30,
          );
    
          user.value = mockUser;
          _initializeFormFields();
        } catch (e) {
          errorMessage.value = '加载用户数据失败';
        } finally {
          isLoading.value = false;
        }
      }
    
      // 初始化表单字段
      void _initializeFormFields() {
        if (user.value != null) {
          nameController.text = user.value!.name;
          emailController.text = user.value!.email;
          ageController.text = user.value!.age.toString();
        }
      }
    
      // 更新用户数据 - 模拟 API 调用
      Future<void> updateUser() async {
        if (user.value == null) return;
    
        isLoading.value = true;
        errorMessage.value = '';
    
        try {
          // 模拟网络延迟
          await Future.delayed(const Duration(seconds: 1));
    
          // 更新用户数据
          final updatedUser = UserModel(
            id: user.value!.id,
            name: nameController.text,
            email: emailController.text,
            age: int.parse(ageController.text),
          );
    
          user.value = updatedUser;
          Get.snackbar('成功', '个人资料更新成功',
              backgroundColor: Colors.green, colorText: Colors.white);
        } catch (e) {
          errorMessage.value = '更新个人资料失败';
        } finally {
          isLoading.value = false;
        }
      }
    
      // 导航到详情页
      void navigateToDetailsPage() {
        if (user.value != null) {
          Get.to(() => const UserDetailsPage());
        }
      }
    
      @override
      void onClose() {
        // 释放资源 - 防止内存泄漏
        nameController.dispose();
        emailController.dispose();
        ageController.dispose();
        super.onClose();
      }
    }
    
    // 用户资料页面 - 可复用组件
    class UserProfilePage extends StatelessWidget {
      final String userId;
    
      const UserProfilePage({Key? key, this.userId = '1'}) : super(key: key);
    
      @override
      Widget build(BuildContext context) {
        // 使用依赖注入初始化控制器 - 支持多实例
        final UserProfileController controller =
            Get.put(UserProfileController(), tag: userId);
    
        // 页面初始化时获取用户数据
        if (controller.user.value == null) {
          controller.fetchUser(userId);
        }
    
        return Scaffold(
          appBar: AppBar(
            title: const Text('个人资料'),
            actions: [
              IconButton(
                icon: const Icon(Icons.info),
                onPressed: controller.navigateToDetailsPage,
              ),
            ],
          ),
          body: Obx(() {
            // 根据状态显示不同的 UI
            if (controller.isLoading.value) {
              return const Center(child: CircularProgressIndicator());
            }
    
            if (controller.errorMessage.value.isNotEmpty) {
              return Center(
                child: Text(
                  controller.errorMessage.value,
                  style: const TextStyle(color: Colors.red),
                ),
              );
            }
    
            if (controller.user.value == null) {
              return const Center(child: Text('无用户数据'));
            }
    
            return Padding(
              padding: const EdgeInsets.all(16.0),
              child: Form(
                child: Column(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: [
                    TextFormField(
                      controller: controller.nameController,
                      decoration: const InputDecoration(labelText: '姓名'),
                      validator: controller.validateName,
                    ),
                    TextFormField(
                      controller: controller.emailController,
                      decoration: const InputDecoration(labelText: '邮箱'),
                      validator: controller.validateEmail,
                    ),
                    TextFormField(
                      controller: controller.ageController,
                      decoration: const InputDecoration(labelText: '年龄'),
                      keyboardType: TextInputType.number,
                      validator: controller.validateAge,
                    ),
                    const SizedBox(height: 20),
                    ElevatedButton(
                      onPressed: controller.updateUser,
                      child: const Text('更新资料'),
                    ),
                  ],
                ),
              ),
            );
          }),
        );
      }
    }
    
    // 用户详情页面 - 演示导航功能
    class UserDetailsPage extends StatelessWidget {
      const UserDetailsPage({Key? key}) : super(key: key);
    
      @override
      Widget build(BuildContext context) {
        // 获取已存在的控制器实例
        final UserProfileController controller =
            Get.find<UserProfileController>();
    
        return Scaffold(
          appBar: AppBar(title: const Text('用户详情')),
          body: Center(
            child: controller.user.value == null
                ? const Text('无用户数据')
                : Column(
                    mainAxisAlignment: MainAxisAlignment.center,
                    children: [
                      Text('ID: ${controller.user.value!.id}'),
                      Text('姓名: ${controller.user.value!.name}'),
                      Text('邮箱: ${controller.user.value!.email}'),
                      Text('年龄: ${controller.user.value!.age}'),
                    ],
                  ),
          ),
        );
      }
    }  

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值