You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用GetX实现Flutter注册页面全屏加载遮罩?

Flutter GetX实现注册页面全屏加载遮罩方案

一、修正控制器的状态变量

首先把控制器里的普通isloading改成可观察的Rx变量,这样GetX才能自动监听状态变化:

class AuthenticationController extends GetxController{
  // 替换原来的bool isloading = false;
  final RxBool isloading = false.obs;

  void loadingbar() {
    isloading.value = true;
  }

  void loadingbaroff() {
    isloading.value = false;
  }

  // 其他方法保持不变,记得在catch块里添加错误提示
  Future<void> createUserWithEmailAndPassword(Map<String,String> userData) async {
    loadingbar();
    try {
      await Auth().createUserwithEmailAndPassword(email:userData['e-mail']!, password:userData['password']!);
      Get.to(()=>Nav());
    } on FirebaseAuthException catch (e) {
      errormessage = e.message!;
      if (kDebugMode) {
        print(e);
      }
      // 给用户显示错误提示
      Get.snackbar('注册失败', errormessage,
          icon: const Icon(Icons.error_outline, color: Colors.redAccent),
          backgroundColor: Colors.white,
          colorText: Colors.redAccent);
    }
    loadingbaroff();
  }
}

二、修改注册按钮的点击逻辑

原来的按钮点击只存储了数据,没有调用控制器的注册方法,现在补上异步调用:

// 先修改toMap方法让它返回数据
Map<String,String> toMap(){
  return ({
    "first_name":_controller_firstname.text.toString(),"last_name":_controller_lastname.text.toString(),"public_name":_controller_publicname.text.toString(),
    "password":_controller_password.text.toString(),"mobile_num":_controllerphone_number.text.toString(),
    "emergency_num":_controller_emergencynumber.text.toString(),"e-mail":_controller_email.text.toString(),
    "postal_code":_controller_postalcode.text.toString(),"birth_year":_controller_birthyear.text.toString(),
    "user_role":selectpartycontroller.text.toString(),
  });
}

// 注册按钮的onPressed修改为:
onPressed: () async {
  final FormState? form = _formkey.currentState;
  try {
    if (form!.validate() && selectpartycontroller.text.isNotEmpty) {
      Map<String,String> userData = toMap();
      Userbox.write('userdata',userData);
      // 调用控制器的注册和存储用户方法
      await authcontroller.createUserWithEmailAndPassword(userData);
      await authcontroller.addUser(userData);
    } else {
      Get.snackbar('提示', '请填写完整表单信息',
          icon: const Icon(Icons.error_outline, color: Colors.redAccent),
          backgroundColor: Colors.white,
          colorText: Colors.redAccent);
    }
  } catch (e) {
    if (kDebugMode) {
      print(e);
    }
  }
},

三、添加全屏加载遮罩

用Stack包裹原页面内容,通过Obx监听控制器的isloading状态,动态显示遮罩层:

@override
Widget build(BuildContext context) {
  AuthenticationController authcontroller = Get.put(AuthenticationController());
  return Scaffold(
    backgroundColor: Colors.redAccent,
    appBar: AppBar(
      elevation: 0,
      backgroundColor: Colors.transparent,
      centerTitle: true,
      title: const Text('Helping hands',style: TextStyle(fontSize:25,color: Colors.white),),
    ),
    body: Obx(() {
      return Stack(
        children: [
          // 原页面内容
          Container(
            height:MediaQuery.of(context).size.height,
            width: MediaQuery.of(context).size.width,
            margin: const EdgeInsets.all(16),
            child: SingleChildScrollView(
              child: Form(
                key: _formkey,
                child: Column(
                  // 原表单组件保持不变
                ),
              ),
            ),
          ),
          // 加载遮罩层
          if (authcontroller.isloading.value)
            Container(
              color: Colors.black.withOpacity(0.6), // 半透明背景阻止交互
              width: double.infinity,
              height: double.infinity,
              child: const Center(
                child: CircularProgressIndicator(color: Colors.white), // 加载指示器
              ),
            ),
        ],
      );
    }),
  );
}

核心说明

  • 遮罩层用半透明黑色背景覆盖全屏,同时居中显示加载指示器,既阻止用户交互又给出加载反馈。
  • 利用GetX的Obx自动监听isloading状态变化,无需手动调用setState或update()。
  • 异步方法必须加await,确保加载状态在注册流程完成后才关闭。

内容的提问来源于stack exchange,提问作者Abhiram

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 02:25:49