出于学习目的,我正在尝试进行gmail克隆,我正在努力编辑新邮件时输入的多电子邮件。我需要笨拙地听“ ENTER”或“ SPACE”,以便我可以用电子邮件“ block”修改输入(验证后):
我认为我可以使用“ ENTER”键的onFieldSubmitted标记,但是如何更改输入文本?我尝试过:
controller.text = Container();
但是“文本”仅接受String(这似乎是逻辑)。
目标是做完全相同的inputField,在其中将“标记”放在StackOverflow上。
我还找到了EmailInputElement,但是我不知道如何正确使用它,似乎它不是小部件。
如果有人有任何想法,将不胜感激,谢谢。
答案 0 :(得分:1)
这里的窍门是显示如下所示的理想UI,InputDecoration.collapsed()
帮助我们将TextField
最小化,您可以在主列的最后一个小部件中添加Divider()
描绘所有这些都在TextField
我试图模拟您要实现的行为。
我使用TextField
方法检查onChange
中的字符串输入末尾是否有空格,对于enter
按钮,我使用onEditingComplete
函数。
我在电子邮件行上设置了限制,使其只能增长到一定的视口宽度,您也可以使用其他布局。
class Test extends StatefulWidget {
@override
_TestState createState() => _TestState();
}
class _TestState extends State<Test> {
List<String> emails = [];
TextEditingController _emailController;
@override
void initState() {
super.initState();
_emailController = TextEditingController();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: Container(
child: Center(
child: Row(
children: <Widget>[
Container(
constraints: BoxConstraints(maxWidth: 200, minWidth: 0),
child: SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
...emails
.map((email) => Chip(label: Text(email)))
.toList(),
],
),
),
),
Expanded(
child: TextField(
decoration: InputDecoration.collapsed(hintText: 'EMail'),
controller: _emailController,
onChanged: (String val) {
if (val.endsWith(' '))
setState(() {
emails.add(_emailController.text);
_emailController.text = '';
});
},
onEditingComplete: () {
setState(() {
emails.add(_emailController.text);
_emailController.text = '';
});
},
),
)
],
),
)),
),
);
}
}
答案 1 :(得分:0)
如果有人来这里需要我提供的模板所具有的相同功能,则可以将其粘贴到新文件中,然后在需要时调用EmailInput()
。您只想使用带有功能的setList
属性来更新您的List<String>
,以将数据返回到您的父组件中:)它还检查输入的字符串是否是有效的电子邮件。>
它看起来像这样:
import 'package:flutter/material.dart';
class EmailInput extends StatefulWidget {
final Function setList;
final String hint;
final List<String> parentEmails;
const EmailInput({Key key, this.setList, this.hint, this.parentEmails}) : super(key: key);
@override
_EmailInputState createState() => _EmailInputState();
}
class _EmailInputState extends State<EmailInput> {
TextEditingController _emailController;
String lastValue = '';
List<String> emails = [];
FocusNode focus = FocusNode();
@override
void initState() {
super.initState();
_emailController = TextEditingController();
focus.addListener(() {
if (!focus.hasFocus) {
updateEmails();
}
});
}
@override
Widget build(BuildContext context) {
return Container(
child: Center(
child: Column(
children: <Widget>[
Container(
constraints: BoxConstraints(
minWidth: 0,
),
child: SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: Column(
children: <Widget>[
...emails
.map(
(email) => Chip(
avatar: CircleAvatar(
backgroundColor: Colors.black,
child: Text(
email.substring(0, 1),
style: TextStyle(color: Colors.white),
),
),
labelPadding: EdgeInsets.all(4),
backgroundColor: Color.fromARGB(255, 39, 182, 192),
label: Text(
email,
style: TextStyle(fontSize: 16, color: Colors.white),
),
onDeleted: () => {
setState(() {
emails.removeWhere((element) => email == element);
})
},
),
)
.toList(),
],
),
),
),
TextField(
keyboardType: TextInputType.emailAddress,
decoration: InputDecoration.collapsed(hintText: widget.hint),
controller: _emailController,
focusNode: focus,
onChanged: (String val) {
setState(() {
if (val != lastValue) {
lastValue = val;
if (val.endsWith(' ') && validateEmail(val.trim())) {
if (!emails.contains(val.trim())) {
emails.add(val.trim());
widget.setList(emails);
}
_emailController.clear();
} else if (val.endsWith(' ') && !validateEmail(val.trim())) {
_emailController.clear();
}
}
});
},
onEditingComplete: () {
updateEmails();
},
)
],
),
));
}
updateEmails() {
setState(() {
if (validateEmail(_emailController.text)) {
if (!emails.contains(_emailController.text)) {
emails.add(_emailController.text.trim());
widget.setList(emails);
}
_emailController.clear();
} else if (!validateEmail(_emailController.text)) {
_emailController.clear();
}
});
}
setEmails(List<String> emails) {
this.emails = emails;
}
}
bool validateEmail(String value) {
Pattern pattern =
r'^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$';
RegExp regex = new RegExp(pattern);
return regex.hasMatch(value);
}