Flutter使制作漂亮的交互式用户界面变得更加简单和容易。但是,许多flutter开发人员在使用屏幕下方的软键盘输入时遇到了一个问题。问题是,每当用户尝试在屏幕下方填写输入表单(其父小部件是Card、Container或类似的东西)时,软键盘往往会覆盖该表单。下面将复制相同的问题,并将显示此问题的简单解决方案。
问题:
在这里,在下面的应用程序中,您可以看到,每当用户尝试填写输入表单时,软键盘都会覆盖表单,用户无法在不从键盘返回的情况下移动到另一行。
下面是需要改进的部分的代码。它主要包含输入表单和一些处理输入的函数。如果我们查看输入表单的小部件树,我们可以看到组成表单的父小部件只是一个简单的Card,它进一步包含两个TextField 、一个带有日期选择的Container和一个RaisedButton 。
Dart
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
class NewTransaction extends StatefulWidget {
final Function addTx;
NewTransaction(this.addTx);
@override
_NewTransactionState createState() => _NewTransactionState();
}
class _NewTransactionState extends State {
final _titleController = TextEditingController();
final _amountController = TextEditingController();
DateTime _selectedDate;
void _submitData() {
if (_amountController.text.isEmpty) {
return;
}
final enteredTitle = _titleController.text;
final enteredAmount = double.parse(_amountController.text);
if (enteredTitle.isEmpty || enteredAmount <= 0 || _selectedDate == null) {
return;
}
widget.addTx(
enteredTitle,
enteredAmount,
_selectedDate,
);
Navigator.of(context).pop();
}
void _presentDatePicker() {
showDatePicker(
context: context,
initialDate: DateTime.now(),
firstDate: DateTime(2019),
lastDate: DateTime(2022),
).then((pickedDate) {
if (pickedDate == null) {
return;
}
setState(() {
_selectedDate = pickedDate;
});
});
print('...');
}
@override
// widget tree for the card starts hear
// this is the element which appear on
// tap of the floating action button
Widget build(BuildContext context) {
return Card(
elevation: 5,
child: Column(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
TextField(
decoration: InputDecoration(labelText: 'Title'),
controller: _titleController,
onSubmitted: (_) => _submitData(),),
//TetFiled
TextField(
decoration: InputDecoration(labelText: 'Amount'),
controller: _amountController,
keyboardType: TextInputType.number,
onSubmitted: (_) => _submitData(),),
Container(
height: 70,
child: Row(
children: [
Expanded(
child: Text(
_selectedDate == null
? 'No Date Chosen!'
: 'Picked Date: ${DateFormat.yMd().format(_selectedDate)}',
),//Text
),//Expand
FlatButton(
textColor: Theme.of(context).primaryColor,
child: Text(
'Choose Date',
style: TextStyle(
fontWeight: FontWeight.bold,
),//TextStyle
),//Text
onPressed: _presentDatePicker,
),//FlatButton
],//[]
),//Row
),//Container
RaisedButton(
child: Text('Add Transaction'),
color: Theme.of(context).primaryColor,
textColor: Theme.of(context).textTheme.button.color,
onPressed: _submitData,
),//RaisedButton
],//[]
),//Column
);//Card
}
}
Dart
// Snippet of the Input form widget tree
return SingleChildScrollView(
// change 3
child: Card(
elevation: 5,
child: Container(
padding: EdgeInsets.only(
// change 1
top: 10,
bottom: MediaQuery.of(context).viewInsets.bottom + 10,
// chage 2
left: 10,
right: 10),
解决方案:
我们想要实现的解决方案是,每当用户点击TextFiled并且键盘出来时,输入表单也应该向上移动,其高度与键盘的高度相同,并且表单应该是可滚动的以便于访问。这可以通过以下步骤实现:
- 在Card小部件的填充中将EdgeInsets.all替换为EdgeInsets.only 。这将使我们能够控制单个填充。
- 在padding的底部参数中, 我们将使用MediaQuery ( MediaQuery.of(context).viewInsets.bottom ) 来了解键盘的高度并将其添加到底部填充中。这样我们每当键盘出现时,表单都会向上移动,高度等于键盘的高度。
- 最后,我们将使用SingleChildScrollView包装整个输入表单,使其可滚动。这将使切换到下一个输入字段更容易。
Dart
// Snippet of the Input form widget tree
return SingleChildScrollView(
// change 3
child: Card(
elevation: 5,
child: Container(
padding: EdgeInsets.only(
// change 1
top: 10,
bottom: MediaQuery.of(context).viewInsets.bottom + 10,
// chage 2
left: 10,
right: 10),
这是输入表单在更正后的行为方式。输入表单根据软键盘的高度向上移动,使所有字段都可见。除此之外,表单现在也可以滚动。
想要一个更快节奏和更具竞争力的环境来学习 Android 的基础知识吗?
单击此处前往由我们的专家精心策划的指南,旨在让您立即做好行业准备!