当焦点在 TextField 上并且键盘在 Flutter 中打开时如何向上推送内容?
How to push content up when focus is on TextField and keyboard opens in Flutter?
当焦点位于 'Description' TextField 且键盘打开时,我需要将我的内容上推
without keyboard
Actual result
Expected result
ListView(
children: [
Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('Title'),
TitleField(
controller: titleEditingController,
),
Text(
'Description',
),
DescriptionField(
focusNode: _focusNode,
controller: descriptionEditingController),
DCDatePicker(),
],
),
AddButton(),
],
),
],
);
请参考以下代码
使用 ScrollController,当 Description TextField 处于 onTapped 和 onFocus 时,您可以通过添加这段代码滚动到底部
_controller.animateTo(
_controller.position.maxScrollExtent,
duration: Duration(seconds: 1),
curve: Curves.fastOutSlowIn,
);
final _controller = ScrollController();
ListView(
controller: _controller,
children: [
Column(
children: [
Text('Title'),
TitleField(
controller: titleEditingController,
),
Text(
'Description',
),
DescriptionField(
focusNode: _focusNode,
controller: descriptionEditingController),
DCDatePicker(),
],
),
SizedBox(
height: 15.0,
),
AddButton(),
SizedBox(
height: 250.0,
), // Add space at end of list view so it allows to scroll
],
),
请参考下面的示例代码
class MainScreen extends StatefulWidget {
MainScreen({Key key}) : super(key: key);
@override
_MainScreenState createState() => _MainScreenState();
}
class _MainScreenState extends State<MainScreen> {
final TextEditingController emailController = TextEditingController();
final FocusNode emailFocus = FocusNode();
final TextEditingController pswdController = TextEditingController();
final FocusNode pswdFocus = FocusNode();
final _validationKey = GlobalKey<FormState>();
@override
void initState() {
super.initState();
}
@override
void dispose() {
super.dispose();
}
int validateEmail(String emailAddress) {
String patttern = r'^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$';
RegExp regExp = new RegExp(patttern);
if (emailAddress.isEmpty || emailAddress.length == 0) {
return 1;
} else if (!regExp.hasMatch(emailAddress)) {
return 2;
} else {
return 0;
}
}
int validatePassword(String pswd) {
if (pswd.isEmpty || pswd.length == 0) {
return 1;
} else if (pswd != null && pswd.isNotEmpty && pswd.length <= 8) {
return 2;
} else {
return 0;
}
}
final _controller = ScrollController();
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Colors.lightBlue,
automaticallyImplyLeading: true,
leading: Icon(
Icons.arrow_back,
),
title: Text("Example"),
centerTitle: true,
),
body: Container(
padding: EdgeInsets.all(15.0),
child: ListView(
controller: _controller,
children: [
Form(
key: _validationKey,
child: Column(
children: [
/* Email */
TextFormField(
autovalidateMode: AutovalidateMode.onUserInteraction,
/* autovalidate is disabled */
controller: emailController,
keyboardType: TextInputType.emailAddress,
onChanged: (val) {},
maxLines: 1,
validator: (value) {
int res = validateEmail(value);
if (res == 1) {
return "Please fill email address";
} else if (res == 2) {
return "Please enter valid email address";
} else {
return null;
}
},
focusNode: emailFocus,
autofocus: false,
decoration: InputDecoration(
errorMaxLines: 3,
counterText: "",
filled: true,
fillColor: Colors.white,
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(4)),
borderSide: BorderSide(
width: 1,
color: Color(0xffE5E5E5),
),
),
disabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(4)),
borderSide: BorderSide(
width: 1,
color: Color(0xffE5E5E5),
),
),
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(4)),
borderSide: BorderSide(
width: 1,
color: Color(0xffE5E5E5),
),
),
border: OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(4)),
borderSide: BorderSide(
width: 1,
),
),
errorBorder: OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(4)),
borderSide: BorderSide(
width: 1,
color: Colors.red,
)),
focusedErrorBorder: OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(4)),
borderSide: BorderSide(
width: 1,
color: Colors.red,
),
),
hintText: "Enter email address" ?? "",
),
),
SizedBox(
height: 15.0,
),
/* Password */
TextFormField(
autovalidateMode: AutovalidateMode.onUserInteraction,
/* autovalidate is disabled */
controller: pswdController,
inputFormatters: [
FilteringTextInputFormatter.deny(RegExp(r"\s\s")),
FilteringTextInputFormatter.deny(RegExp(
r'(\u00a9|\u00ae|[\u2000-\u3300]|\ud83c[\ud000-\udfff]|\ud83d[\ud000-\udfff]|\ud83e[\ud000-\udfff])')),
],
keyboardType: TextInputType.text,
onChanged: (val) {},
maxLines: 15,
validator: (value) {
int res = validatePassword(value);
if (res == 1) {
return "Please enter password";
} else if (res == 2) {
return "Please enter minimum 9 characters";
} else {
return null;
}
},
focusNode: pswdFocus,
autofocus: false,
onTap: () {
_controller.animateTo(
_controller.position.maxScrollExtent,
duration: Duration(seconds: 1),
curve: Curves.fastOutSlowIn,
);
},
decoration: InputDecoration(
errorMaxLines: 3,
counterText: "",
filled: true,
fillColor: Colors.white,
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(4)),
borderSide: BorderSide(
width: 1,
color: Color(0xffE5E5E5),
),
),
disabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(4)),
borderSide: BorderSide(
width: 1,
color: Color(0xffE5E5E5),
),
),
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(4)),
borderSide: BorderSide(
width: 1,
color: Color(0xffE5E5E5),
),
),
border: OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(4)),
borderSide: BorderSide(
width: 1,
),
),
errorBorder: OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(4)),
borderSide: BorderSide(
width: 1,
color: Colors.red,
)),
focusedErrorBorder: OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(4)),
borderSide: BorderSide(
width: 1,
color: Colors.red,
),
),
hintText: "Enter password" ?? "",
),
),
],
),
),
SizedBox(
height: 15.0,
),
OutlinedButton(
onPressed: () {
_validationKey.currentState.validate();
if (emailController.text.isEmpty) {
emailFocus.requestFocus();
} else if (pswdController.text.isEmpty ||
pswdController.text.length <= 8) {
pswdFocus.requestFocus();
_controller.animateTo(
_controller.position.maxScrollExtent,
duration: Duration(seconds: 1),
curve: Curves.fastOutSlowIn,
);
}
},
child: Text("Validate"),
),
SizedBox(
height: 250.0,
),
],
),
),
);
}
}
当焦点位于 'Description' TextField 且键盘打开时,我需要将我的内容上推
without keyboard
Actual result
Expected result
ListView(
children: [
Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('Title'),
TitleField(
controller: titleEditingController,
),
Text(
'Description',
),
DescriptionField(
focusNode: _focusNode,
controller: descriptionEditingController),
DCDatePicker(),
],
),
AddButton(),
],
),
],
);
请参考以下代码
使用 ScrollController,当 Description TextField 处于 onTapped 和 onFocus 时,您可以通过添加这段代码滚动到底部
_controller.animateTo(
_controller.position.maxScrollExtent,
duration: Duration(seconds: 1),
curve: Curves.fastOutSlowIn,
);
final _controller = ScrollController();
ListView(
controller: _controller,
children: [
Column(
children: [
Text('Title'),
TitleField(
controller: titleEditingController,
),
Text(
'Description',
),
DescriptionField(
focusNode: _focusNode,
controller: descriptionEditingController),
DCDatePicker(),
],
),
SizedBox(
height: 15.0,
),
AddButton(),
SizedBox(
height: 250.0,
), // Add space at end of list view so it allows to scroll
],
),
请参考下面的示例代码
class MainScreen extends StatefulWidget {
MainScreen({Key key}) : super(key: key);
@override
_MainScreenState createState() => _MainScreenState();
}
class _MainScreenState extends State<MainScreen> {
final TextEditingController emailController = TextEditingController();
final FocusNode emailFocus = FocusNode();
final TextEditingController pswdController = TextEditingController();
final FocusNode pswdFocus = FocusNode();
final _validationKey = GlobalKey<FormState>();
@override
void initState() {
super.initState();
}
@override
void dispose() {
super.dispose();
}
int validateEmail(String emailAddress) {
String patttern = r'^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$';
RegExp regExp = new RegExp(patttern);
if (emailAddress.isEmpty || emailAddress.length == 0) {
return 1;
} else if (!regExp.hasMatch(emailAddress)) {
return 2;
} else {
return 0;
}
}
int validatePassword(String pswd) {
if (pswd.isEmpty || pswd.length == 0) {
return 1;
} else if (pswd != null && pswd.isNotEmpty && pswd.length <= 8) {
return 2;
} else {
return 0;
}
}
final _controller = ScrollController();
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Colors.lightBlue,
automaticallyImplyLeading: true,
leading: Icon(
Icons.arrow_back,
),
title: Text("Example"),
centerTitle: true,
),
body: Container(
padding: EdgeInsets.all(15.0),
child: ListView(
controller: _controller,
children: [
Form(
key: _validationKey,
child: Column(
children: [
/* Email */
TextFormField(
autovalidateMode: AutovalidateMode.onUserInteraction,
/* autovalidate is disabled */
controller: emailController,
keyboardType: TextInputType.emailAddress,
onChanged: (val) {},
maxLines: 1,
validator: (value) {
int res = validateEmail(value);
if (res == 1) {
return "Please fill email address";
} else if (res == 2) {
return "Please enter valid email address";
} else {
return null;
}
},
focusNode: emailFocus,
autofocus: false,
decoration: InputDecoration(
errorMaxLines: 3,
counterText: "",
filled: true,
fillColor: Colors.white,
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(4)),
borderSide: BorderSide(
width: 1,
color: Color(0xffE5E5E5),
),
),
disabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(4)),
borderSide: BorderSide(
width: 1,
color: Color(0xffE5E5E5),
),
),
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(4)),
borderSide: BorderSide(
width: 1,
color: Color(0xffE5E5E5),
),
),
border: OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(4)),
borderSide: BorderSide(
width: 1,
),
),
errorBorder: OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(4)),
borderSide: BorderSide(
width: 1,
color: Colors.red,
)),
focusedErrorBorder: OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(4)),
borderSide: BorderSide(
width: 1,
color: Colors.red,
),
),
hintText: "Enter email address" ?? "",
),
),
SizedBox(
height: 15.0,
),
/* Password */
TextFormField(
autovalidateMode: AutovalidateMode.onUserInteraction,
/* autovalidate is disabled */
controller: pswdController,
inputFormatters: [
FilteringTextInputFormatter.deny(RegExp(r"\s\s")),
FilteringTextInputFormatter.deny(RegExp(
r'(\u00a9|\u00ae|[\u2000-\u3300]|\ud83c[\ud000-\udfff]|\ud83d[\ud000-\udfff]|\ud83e[\ud000-\udfff])')),
],
keyboardType: TextInputType.text,
onChanged: (val) {},
maxLines: 15,
validator: (value) {
int res = validatePassword(value);
if (res == 1) {
return "Please enter password";
} else if (res == 2) {
return "Please enter minimum 9 characters";
} else {
return null;
}
},
focusNode: pswdFocus,
autofocus: false,
onTap: () {
_controller.animateTo(
_controller.position.maxScrollExtent,
duration: Duration(seconds: 1),
curve: Curves.fastOutSlowIn,
);
},
decoration: InputDecoration(
errorMaxLines: 3,
counterText: "",
filled: true,
fillColor: Colors.white,
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(4)),
borderSide: BorderSide(
width: 1,
color: Color(0xffE5E5E5),
),
),
disabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(4)),
borderSide: BorderSide(
width: 1,
color: Color(0xffE5E5E5),
),
),
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(4)),
borderSide: BorderSide(
width: 1,
color: Color(0xffE5E5E5),
),
),
border: OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(4)),
borderSide: BorderSide(
width: 1,
),
),
errorBorder: OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(4)),
borderSide: BorderSide(
width: 1,
color: Colors.red,
)),
focusedErrorBorder: OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(4)),
borderSide: BorderSide(
width: 1,
color: Colors.red,
),
),
hintText: "Enter password" ?? "",
),
),
],
),
),
SizedBox(
height: 15.0,
),
OutlinedButton(
onPressed: () {
_validationKey.currentState.validate();
if (emailController.text.isEmpty) {
emailFocus.requestFocus();
} else if (pswdController.text.isEmpty ||
pswdController.text.length <= 8) {
pswdFocus.requestFocus();
_controller.animateTo(
_controller.position.maxScrollExtent,
duration: Duration(seconds: 1),
curve: Curves.fastOutSlowIn,
);
}
},
child: Text("Validate"),
),
SizedBox(
height: 250.0,
),
],
),
),
);
}
}