After pressing TextButton there should be a loading until getting response from Api.
For example: I have login TextButton, then after pressing the button CircularProgressIndicator will be shown and stop when the response is received and move to next page.
Please help me to solve this
import "dart:convert";
import 'package:http/http.dart' as http;
import 'register.dart';
import 'package:crypto/crypto.dart';
void main() => runApp(const MaterialApp(
home: LoginScreen(),
));
class LoginScreen extends StatefulWidget {
const LoginScreen({Key? key}) : super(key: key);
@override
State<LoginScreen> createState() => _LoginScreenState();
}
class _LoginScreenState extends State<LoginScreen> {
bool passwordVisible = false;
late String email;
late String password1;
var md5password = "";
late SharedPreferences prefs;
@override
void initState() {
super.initState();
initSharedPref();
passwordVisible = true;
}
void initSharedPref() async {
prefs = await SharedPreferences.getInstance();
}
String generateMd5(String input) {
return md5.convert(utf8.encode(input)).toString();
}
GlobalKey<FormState> formKey = GlobalKey<FormState>();
final emailController = TextEditingController();
final passwordController = TextEditingController();
@override
void dispose() {
super.dispose();
//clean up the controller when widget is disposed.
emailController.dispose();
passwordController.dispose();
}
@override
Widget build(BuildContext context) {
double height = MediaQuery.of(context).size.height;
double width = MediaQuery.of(context).size.width;
return WillPopScope(
onWillPop: () async {
return false;
},
child: Scaffold(
backgroundColor: Colors.white,
body: SingleChildScrollView(
child: Form(
key: formKey,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
height: height * 0.30,
width: double.infinity,
decoration: const BoxDecoration(color: Colors.white),
child: Column(
mainAxisAlignment: MainAxisAlignment.end,
children: [
Image.asset(
"assets/title.png",
width: 350.0,
),
const SizedBox(
height: 30,
),
],
),
),
const SizedBox(
height: 50,
),
const Center(
child: Text('Login',
style: TextStyle(
fontSize: 30.0,
fontWeight: FontWeight.bold,
color: Colors.black,
)),
),
const SizedBox(height: 30),
Center(
child: SizedBox(
height: height * 0.08,
width: width - 35,
child: TextFormField(
controller: emailController,
validator: (email) {
if (email == null || email.isEmpty) {
return "Please enter Email";
} else if (!email.contains("@") ||
!email.contains(".")) {
return "Please enter a valid email address";
}
return null;
},
onChanged: (value) {
setState(() {
email = value;
});
},
decoration: const InputDecoration(
border: OutlineInputBorder(),
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(color: Colors.black)),
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(color: Color(0xFF006ff6)),
),
prefixIcon: Icon(Icons.email, color: Color(0xFF006ff6)),
labelText: mail,
labelStyle:
TextStyle(color: Colors.grey, fontSize: 13.0),
),
),
),
),
const SizedBox(height: 30),
Center(
child: SizedBox(
height: height * 0.08,
width: width - 35,
child: TextFormField(
controller: passwordController,
validator: (password) {
if (password == null || password.isEmpty) {
return "Please enter your password";
}
return null;
},
onChanged: (value) {
setState(() {
password1 = value;
});
md5password = generateMd5(password1);
print(md5password);
},
obscureText: passwordVisible,
obscuringCharacter: "*",
decoration: InputDecoration(
border: const OutlineInputBorder(),
enabledBorder: const OutlineInputBorder(
borderSide: BorderSide(color: Colors.black)),
focusedBorder: const OutlineInputBorder(
borderSide: BorderSide(color: Color(0xFF006ff6)),
),
prefixIcon: const Icon(Icons.lock_open,
color: Color(0xFF006ff6)),
labelText: password,
labelStyle:
const TextStyle(color: Colors.grey, fontSize: 13.0),
suffixIcon: IconButton(
icon: Icon(passwordVisible
? Icons.visibility
: Icons.visibility_off),
onPressed: () {
setState(() {
passwordVisible = !passwordVisible;
});
},
),
),
),
),
),
Align(
alignment: Alignment.centerRight,
child: TextButton(
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => const ForgotPass()));
},
child: const Text(
"Forgot your Password ?",
style: TextStyle(
color: Colors.grey,
decoration: TextDecoration.underline),
),
),
),
const SizedBox(height: 20),
Center(
child: SizedBox(
height: height * 0.08,
width: width - 35,
child: TextButton(
onPressed: () async {
if (formKey.currentState!.validate()) {
print(email);
print(md5password);
loginUser();
},
style: TextButton.styleFrom(
backgroundColor: Color(0xFF006ff6),
shadowColor: Colors.black,
elevation: 5,
shape: const RoundedRectangleBorder(
borderRadius:
BorderRadius.all(Radius.circular(10)))),
child: const Text(
"SIGN IN",
style: TextStyle(
color: Colors.white,
fontSize: 20.0,
fontWeight: FontWeight.bold,
),
),
),
),
),
const SizedBox(
height: 20.0,
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const Text(
"Don't have an account?",
style: TextStyle(color: Colors.grey),
),
TextButton(
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => const Register()));
},
child: const Text(
"Sign up",
style: TextStyle(color: Colors.black),
))
],
)
],
),
),
),
),
);
}
void loginUser() async {
if (emailController.text.isNotEmpty && passwordController.text.isNotEmpty) {
var reqBody = {
"email": emailController.text,
"password": md5password = generateMd5(passwordController.text)
};
var response = await http.post(
Uri.parse("https://testing.com/user/login"),
headers: {"Content-Type": "application/json"},
body: jsonEncode(reqBody));
if (response.statusCode == 200) {
var jsonResponse = jsonDecode(response.body);
if (jsonResponse['success']) {
var myToken = jsonResponse['data']['token'];
prefs.setString('token', myToken);
print(myToken);
Navigator.push(context,
MaterialPageRoute(
builder: (context) => Dashboard(token: myToken)));
} else {
print('Something went wrong');
}
print(response.statusCode);
}
else if (response.statusCode == 400) {
const snackBar = SnackBar(
content: Text('Incorrect Username or Password'),
backgroundColor: Colors.red,
elevation: 10,
behavior: SnackBarBehavior.floating,
margin: EdgeInsets.all(5),
);
ScaffoldMessenger.of(context).showSnackBar(snackBar);
}
else if(response.statusCode == 500){
const snackBar = SnackBar(
content: Text('Server Error'),
backgroundColor: Colors.red,
elevation: 10,
behavior: SnackBarBehavior.floating,
margin: EdgeInsets.all(5),
);
ScaffoldMessenger.of(context).showSnackBar(snackBar);
} else {
const snackBar = SnackBar(
content: Text('Something went wrong'),
backgroundColor: Colors.red,
elevation: 10,
behavior: SnackBarBehavior.floating,
margin: EdgeInsets.all(5),
);
ScaffoldMessenger.of(context).showSnackBar(snackBar);
}
}
}
}
This is my sample code.
FutureBuilder. Basic implementation:
The widget will update accordingly to api connection and update in real time on new data received after
futurefunction completes.