按下TextButton
后,应加载,直到从API获得响应。
例如:我已经登录TextButton
,然后按下按钮后CircularProgressIndicator
将显示和停止时,收到的响应,并移动到下一页。
请帮我解决这个问题
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);
}
}
}
}
这是我的示例代码。
1条答案
按热度按时间ulydmbyx1#
FutureBuilder。基本实现:
小部件将根据API连接进行更新,并在
future
函数完成后真实的更新接收到的新数据。