我正在开发一个Flutter应用程序,它的登录屏幕包括一个电子邮件和一个密码“TextFormField”。虽然密码字段工作正常,但hintText“电子邮件”没有显示在电子邮件输入字段中,该字段对点击没有响应-它没有获得焦点或调出键盘,奇怪的是,将isPasswordField
布尔值设置为true会使电子邮件字段可交互,并显示提示文本,这不是我想要的电子邮件输入行为。
1.确保电子邮件字段的“obscureText”设置为“false”,密码字段设置为“true”。
2.使用Flutter Inspector检查可能会阻塞电子邮件字段的覆盖小部件。
3.注解掉可能拦截点击的“GestureDetector”小部件。
4.在各种模拟器和物理设备上进行测试,以排除特定于平台的问题。
问题行为:
电子邮件TextFormField
是可见的,但不响应点击,使其无法输入文本。除非我将isPasswordField
设置为true,否则此行为将持续存在,这应该控制密码字段的可见性切换,而不是电子邮件字段。
Code Snippets:
- 登录_页面.dart:*
` dart
import 'package:first_app/features/user_auth/presentation/pages/sign_up_page.dart';
import 'package:flutter/material.dart';
import 'package:first_app/features/user_auth/presentation/widgets/form_container_widget.dart';
import 'package:first_app/features/user_auth/presentation/pages/home_page.dart';
class LoginPage extends StatefulWidget {
const LoginPage({Key? key}) : super(key: key);
@override
// ignore: library_private_types_in_public_api
_LoginPageState createState() => _LoginPageState();
}
class _LoginPageState extends State<LoginPage> {
final TextEditingController emailController = TextEditingController();
final TextEditingController passwordController = TextEditingController();
@override
void initState() {
super.initState();
emailController.addListener(() {
print('Email text: ${emailController.text}'); // For debugging purposes
});
passwordController.addListener(() {
print('Password text: ${passwordController.text}');
});
}
@override
void dispose() {
// Dispose of the TextEditingController when the widget is removed
emailController.dispose();
passwordController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
resizeToAvoidBottomInset: true, // Ensures the keyboard doesn't overflow
appBar: AppBar(
title: const Text('Login Page'),
),
body: SingleChildScrollView(
// Ensures the content is scrollable and bounds are provided
child: Center(
child: ConstrainedBox(
constraints: BoxConstraints(
minHeight: MediaQuery.of(context).size.height,
),
child: IntrinsicHeight(
// Constrains the Column's height
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const Text(
"Login",
style: TextStyle(fontSize: 27, fontWeight: FontWeight.bold),
),
const SizedBox(
height: 10,
),
FormContainerWidget(
//TextField(
controller: emailController,
//decoration: InputDecoration(
hintText: 'Email',
isPasswordField: false,
inputType: TextInputType.emailAddress,
),
const SizedBox(
height: 10,
),
FormContainerWidget(
controller: passwordController,
hintText: 'Password',
isPasswordField: true,
),
const SizedBox(height: 30),
GestureDetector(
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => const HomePage()));
},
child: Container(
width: MediaQuery.of(context).size.width * 0.8,
decoration: BoxDecoration(
color: Colors.blue,
borderRadius: BorderRadius.circular(10),
),
child: TextButton(
onPressed: () {
print(
'Login button pressed'); // For debugging purposes
},
child: const Text(
'Login',
style: TextStyle(
color: Colors.white, fontWeight: FontWeight.bold),
),
),
),
),
// Add more widgets as needed
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const Text('Don\'t have an account?'),
TextButton(
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => const SignUpPage()));
print(
'Sign Up button pressed'); // For debugging purposes
},
child: const Text(
'Sign Up',
style: TextStyle(
color: Colors.blue, fontWeight: FontWeight.bold),
),
),
],
)
],
),
),
),
),
),
);
}
}
字符串
- form_*container_widget.dart
import 'package:flutter/material.dart';
//import 'package:flutter/services.dart';
class FormContainerWidget extends StatefulWidget {
//properties
final TextEditingController controller;
final Key? fieldKey;
final bool isPasswordField;
final String hintText;
final String? labelText;
final String? helperText;
final FormFieldSetter<String>? onSaved;
final FormFieldValidator<String>? validator;
final ValueChanged<String>? onFieldSubmitted;
final TextInputType? inputType;
const FormContainerWidget({
//paramaters
Key? key,
required this.controller,
this.isPasswordField = false,
this.fieldKey,
required this.hintText,
this.labelText,
this.helperText,
this.onSaved,
this.validator,
this.onFieldSubmitted,
this.inputType,
}) : super(key: key);
@override
// ignore: library_private_types_in_public_api
_FormContainerWidgetState createState() => _FormContainerWidgetState();
}
class _FormContainerWidgetState extends State<FormContainerWidget> {
bool _obscureText = true;
@override
Widget build(BuildContext context) {
print('Building FormContainerWidget'); // For debugging purposes
print('Controller: ${widget.controller}');
return Container(
width: MediaQuery.of(context).size.width * 0.8, // 80% of screen width
decoration: BoxDecoration(
color: Colors.grey.withOpacity(.35),
borderRadius: BorderRadius.circular(10),
),
child: ConstrainedBox(
constraints: const BoxConstraints(
// Set a minimum and maximum height if needed
minHeight: 40.0, // Example minimum height
maxHeight: 50.0, // Example maximum height
),
child: TextFormField(
style: const TextStyle(color: Colors.blue),
controller: widget.controller,
keyboardType: widget.inputType,
key: widget.fieldKey,
obscureText: widget.isPasswordField == true ? _obscureText : false,
onSaved: widget.onSaved,
validator: widget.validator,
onFieldSubmitted: widget.onFieldSubmitted,
onChanged: (text) {
// For debugging purposes
print('Input text: $text');
},
decoration: InputDecoration(
border: OutlineInputBorder(), // Add a border for testing purposes
//border: InputBorder.none,
filled: true,
hintText: widget.hintText,
hintStyle: const TextStyle(color: Colors.black45),
suffixIcon: GestureDetector(
onTap: () {
setState(() {
_obscureText = !_obscureText;
});
},
child: widget.isPasswordField == true
? Icon(
_obscureText ? Icons.visibility_off : Icons.visibility,
color: _obscureText == false ? Colors.blue : Colors.grey,
)
: null,
),
),
),
),
);
}
}
型
1条答案
按热度按时间5hcedyr01#
在
_FormContainerWidgetState
中,有条件地设置GestureDetector
的Icon
。相反,将该检查移动到GestureDetector
本身:字符串