I have a project which uses getx state management and in the register section When a user clicks the register button I want to show a loading bar on top of all widgets that blocks out the user interaction with the text fields,
I will give my getx controller and UI below
getx controller
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/foundation.dart';
import 'package:get/get.dart';
import 'package:helping_hand/UI/Map/Mappage.dart';
import 'package:helping_hand/drawers/bottomnavbar.dart';
import '../Utils/Auth.dart';
class AuthenticationController extends GetxController{
late String errormessage;
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);
}
}
loadingbaroff();
}
//cloud firestore using firestore
final CollectionReference citizen = FirebaseFirestore.instance.collection('citizen');
Future<void>addUser(Map<String,String> userData)async{
loadingbar();
try{
await citizen.doc(userData['e-mail']).set({
"first_name":userData['first_name'],"last_name":userData['last_name'],"public_name":userData['public_name'],
"password":userData['password'],"mobile_num":userData['mobile_num'],
"emergency_num":userData['emergency_num'],"e-mail":userData['e-mail'],
"postal_code":userData['postal_code'],"birth_year":userData['birth_year'],
"user_role":userData['user_role'],
});
}catch(err){
if (kDebugMode) {
print(err);
}
}
loadingbaroff();
}
Future<void> signInWithEmailAndPassword(String email,String password) async {
loadingbar();
try {
await Auth().signInwithEmailAndPassword(email: email, password:password);
Get.to(()=>Nav());
} on FirebaseAuthException catch (e) {
var errormessage2 = e.message!;
if (kDebugMode) {
print(e);
}
}
loadingbaroff();
}
bool isloading = false;
void loadingbar() {
isloading = true;
update();
}
void loadingbaroff() {
isloading = false;
update();
}
}
Register page:
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:get/get_core/src/get_main.dart';
import 'package:helping_hand/StateManagement/AuthenticationController.dart';
import 'package:helping_hand/UI/Authentication/LoginUser.dart';
import '../../Constants/Constants.dart';
import '../../Utils/Auth.dart';
import '../../drawers/bottomnavbar.dart';
import '../Bottom Navigation/My status.dart';
class RegisterUser extends StatelessWidget {
RegisterUser({Key? key}) : super(key: key);
final TextEditingController _controller_email = TextEditingController();
final TextEditingController _controller_password = TextEditingController();
final TextEditingController _controller_firstname = TextEditingController();
final TextEditingController _controller_lastname = TextEditingController();
final TextEditingController _controller_publicname = TextEditingController();
final TextEditingController _controller_passwordconfirm = TextEditingController();
final TextEditingController _controllerphone_number = TextEditingController();
final TextEditingController _controller_emergencynumber = TextEditingController();
final TextEditingController _controller_postalcode = TextEditingController();
final TextEditingController _controller_birthyear = TextEditingController();
final TextEditingController _controller_countrycode = TextEditingController();
List<String> status = ['Citizen','Private Responder','Provider','Government'];
TextEditingController selectpartycontroller = TextEditingController();
final GlobalKey<FormState> _formkey = GlobalKey<FormState>();
@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: 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(
children: [
const NeumorphicContainer(marginbottom: 10,child:CircleAvatar(backgroundColor: Colors.redAccent,radius:50,backgroundImage: AssetImage('assets/undraw/profilepicture.png'),)),
const Text('Lets Get you Started ',style: TextStyle(fontSize:25,color: Colors.white),),
const SizedBox(height: 30,),
UserTextInput(controller: _controller_firstname,hinttext: 'firstname *',),
UserTextInput(controller: _controller_lastname,hinttext:'lastname *',),
UserTextInput(controller: _controller_publicname,hinttext: 'public Name *',),
UserTextInput(controller: _controller_password,hinttext: 'password 8-character minimum *',obscuretext: true,),
UserTextInput(controller: _controller_passwordconfirm,hinttext: 'confirm password *',obscuretext: true,),
Row(children: [
Expanded(
flex: 1,
child: UserTextInput(controller: _controller_countrycode,hinttext: '+91',)),
Expanded(
flex: 3,
child: UserTextInput(controller: _controllerphone_number,hinttext: 'mobile phone number (10 digits)',)),
],),
UserTextInput(controller: _controller_emergencynumber,hinttext: 'Local government emergency number *',),
UserTextInput(controller: _controller_email,hinttext: 'e-mail *',),
UserTextInput(controller: _controller_postalcode,hinttext: 'postal code',),
UserTextInput(controller: _controller_birthyear,hinttext: 'birth year',),
Listpicker(status: status, selectpartycontroller: selectpartycontroller),
const SizedBox(height: 16,),
NeumorphicContainer(
marginbottom: 24,
child: ElevatedButton(
onPressed: () {
final FormState? form = _formkey.currentState;
try{
if(form!.validate() && selectpartycontroller.text.isNotEmpty){
toMap();
Get.to(()=>Nav());
}else{
Get.snackbar('Fill','Fill form details',
icon: const Icon(Icons.error_outline,color: Colors.redAccent,),backgroundColor: Colors.white,
colorText: Colors.redAccent);
}
}catch(e){
if (kDebugMode) {
print(e);
}
}
},
style: ElevatedButton.styleFrom(backgroundColor: Colors.redAccent),
child: const Text('Register', style: TextStyle(color: Colors.white),
),
),
),
Container(
margin: const EdgeInsets.only(top: 20,bottom: 40),
child: InkWell(
onTap: () {
Get.to(()=>LoginUser());
},
child: const Text(
'Already Registered ?? Click to Login',
style: TextStyle(color: Colors.white))),
),
],
),
),
),
),
);
}
void toMap(){
Map<String,String> userData = ({
"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(),
});
Userbox.write('userdata',userData);
if (kDebugMode) {
var userinfo = Userbox.read('userdata');
print(userinfo['e-mail']);
print('this is data stored :::: ${Userbox.read('userlogindata')}');
print('this is user data ::::${Userbox.read('userdata')}');
}
}
}
class UserTextInput extends StatelessWidget {
final TextEditingController controller;
final String? hinttext;
final bool? obscuretext;
const UserTextInput({
Key? key, required this.controller, this.hinttext, this.obscuretext,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return Container(
margin: const EdgeInsets.only(bottom:16),
padding: const EdgeInsets.all(8),
child: TextFormField(
autovalidateMode: AutovalidateMode.onUserInteraction,
obscureText: obscuretext!=null?true:false,
controller: controller,
validator: (value){
if(value == null||value.isEmpty){
return 'please enter the details';
}
return null;
},
decoration: InputDecoration(
hintStyle: const TextStyle(color:Colors.white),
hintText: hinttext,
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(16.0),
borderSide: const BorderSide(
color: Colors.red,
width: 2.0,
),
),
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(16.0),
borderSide: const BorderSide(
color: Colors.white,
),
),
)),
);
}
}
notice that I am not calling any function from the controller(because I can't figure out how to implement this loading bar on top of all widgets)is there any widgets in flutter that does the job?
You need to create a custom loading in top of all widgets using a Stack
as parent of all. Something like this:
@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: Stack(children: [
//all your last widget form (Container(...
Obx(
() {
if (authcontroller.isloading.value == true) {
return Container(
color: Colors.white.withOpacity(0.5),
child: const Center(
child: CircularProgressIndicator(),
),
);
} else {
return const SizedBox.shrink();
}
},
)
]));
}
But you need to declare isloading
like this:
RxBool isloading = false.obs;