我有一个登录屏幕,我做了一个有状态的自定义文本字段小部件,然后我在登录屏幕中使用这个小部件的电子邮件和密码部分。问题是,当我通过点击文本字段外取消屏幕焦点时,不同文本字段中的所有文本都被删除。我怎样才能摆脱这个问题?
自定义文本字段:
import 'package:flutter/material.dart';
import 'package:flutter_parisa/constants.dart';
class TextInputField extends StatefulWidget {
final String labelText;
final TextEditingController controller;
bool isObscure;
final IconData icon;
final bool hasSuffixIcon;
TextInputField(
{super.key,
required this.labelText,
required this.controller,
required this.icon,
this.isObscure = false,
required this.hasSuffixIcon});
@override
State<TextInputField> createState() => _TextInputFieldState();
}
class _TextInputFieldState extends State<TextInputField> {
final GlobalKey _key = GlobalKey();
void toggleObscure() {
setState(() {
widget.isObscure = !widget.isObscure;
});
}
void unFocus() {
FocusScope.of(context).unfocus();
}
@override
Widget build(BuildContext context) {
return Form(
key: _key,
child: TextFormField(
onTapOutside: (event) {
FocusScope.of(context).unfocus();
},
controller: widget.controller,
obscureText: widget.isObscure,
decoration: InputDecoration(
labelStyle: const TextStyle(color: authbuttonColor),
prefixIconColor: authbuttonColor,
suffixIcon: widget.hasSuffixIcon
? IconButton(
onPressed: () {
toggleObscure();
},
icon: widget.isObscure
? const Icon(
Icons.visibility,
color: authbuttonColor,
)
: const Icon(
Icons.visibility_off,
color: authbuttonColor,
))
: null,
prefixIcon: Icon(widget.icon),
labelText: widget.labelText,
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(5),
borderSide: const BorderSide(
color: authbuttonColor,
)),
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(5),
borderSide: BorderSide(color: focusedBorderColor!)),
),
),
);
}
}
登录界面:
import 'package:flutter/material.dart';
import 'package:flutter_parisa/constants.dart';
import 'package:flutter_parisa/views/screens/auth/forgotpassword_screen.dart';
import 'package:flutter_parisa/views/screens/auth/signup_screen.dart';
import 'package:flutter_parisa/views/widgets/custom_elevated_button.dart';
import 'package:flutter_parisa/views/widgets/custom_text_button.dart';
import 'package:flutter_parisa/views/widgets/text_input_field.dart';
import 'package:get/get.dart';
class LoginScreen extends StatelessWidget {
const LoginScreen({super.key});
@override
Widget build(BuildContext context) {
TextEditingController emailController = TextEditingController();
TextEditingController passwordController = TextEditingController();
return Scaffold(
backgroundColor: authBackgroundColor,
body: SingleChildScrollView(
child: Container(
color: authBackgroundColor,
child: InkWell(
highlightColor: Colors.transparent,
hoverColor: Colors.transparent,
splashColor: Colors.transparent,
onTap: () {
//FocusScope.of(context).requestFocus(FocusNode());
// FocusScopeNode currentFocus = FocusScope.of(context);
// if (!currentFocus.hasPrimaryFocus) {
// currentFocus.unfocus();
// }
//FocusScope.of(context).unfocus();
//FocusManager.instance.primaryFocus?.unfocus();
},
child: SafeArea(
child: SizedBox(
height: MediaQuery.of(context).size.height,
width: MediaQuery.of(context).size.width,
child: Column(
children: [
Container(
height: MediaQuery.of(context).size.height * 0.3,
width: double.infinity,
decoration: const BoxDecoration(
image: DecorationImage(
fit: BoxFit.contain,
image:
AssetImage('assets/images/parisa_logo.png'))),
),
const SizedBox(
height: 40,
width: double.infinity,
child: Padding(
padding: EdgeInsets.only(left: 25),
child: Text(
'Daxil ol',
style: TextStyle(
color: Colors.black,
fontSize: 28,
fontWeight: FontWeight.bold),
),
),
),
//here we have to add custom textfield
Padding(
padding: const EdgeInsets.symmetric(
horizontal: 25, vertical: 5),
child: Column(
children: [
TextInputField(
hasSuffixIcon: false,
labelText: 'Email',
controller: emailController,
icon: Icons.mail),
const SizedBox(
height: 15,
),
TextInputField(
hasSuffixIcon: true,
labelText: 'Şifrə',
controller: passwordController,
icon: Icons.lock,
isObscure: true),
],
),
),
Container(
width: double.infinity,
alignment: Alignment.centerRight,
padding: const EdgeInsets.only(right: 25, bottom: 10),
child: CustomTextButton(
textColor: authbuttonColor,
buttonText: 'Şifrəni Unutduz?',
fontSize: 14,
isBold: true,
onPressed: () {
Get.to(() =>
ForgotPassword(emailContent: emailController));
}),
),
Obx(() {
return Padding(
padding: const EdgeInsets.symmetric(horizontal: 25),
child: authController.isLoading.value
? const Center(
child: CircularProgressIndicator(
color: authbuttonColor,
),
)
: CustomElevatedButton(
fontSize: 24,
buttonColor: authbuttonColor,
buttonName: 'Daxil ol',
onPressed: () {
FocusScope.of(context).unfocus();
authController.loginUser(
emailController.text.trim(),
passwordController.text.trim());
},
textColor: Colors.white,
),
);
}),
SizedBox(
height: MediaQuery.of(context).size.height * 0.1,
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const Text(
'Hesabınız yoxdur?',
style: TextStyle(
color: Colors.grey,
fontSize: 14,
fontWeight: FontWeight.bold),
),
CustomTextButton(
textColor: authbuttonColor,
buttonText: 'Qeydiyyat',
fontSize: 14,
isBold: true,
onPressed: () =>
Get.to(() => const SignUpScreen())),
],
),
),
],
),
),
),
),
),
),
);
}
}
我试过他们所有人分开,但没有帮助。
//FocusScope.of(context).requestFocus(FocusNode());
// FocusScopeNode currentFocus = FocusScope.of(context);
// if (!currentFocus.hasPrimaryFocus) {
// currentFocus.unfocus();
// }
//FocusScope.of(context).unfocus();
//FocusManager.instance.primaryFocus?.unfocus();
1条答案
按热度按时间ki0zmccv1#
你应该把
emailController
和passwordController
作为LoginScreen
的属性,而不是build
方法的局部属性。您还需要在处理
LoginScreen
之后处理TextEditingController
。