TextFormField 上的可点击图标 - 禁用 TextFormField 对图标单击的关注(颤振)
Posted
技术标签:
【中文标题】TextFormField 上的可点击图标 - 禁用 TextFormField 对图标单击的关注(颤振)【英文标题】:Clickable icon on TextFormField - disable TextFormField focus on icon click (Flutter) 【发布时间】:2020-01-25 13:37:30 【问题描述】:我需要一个带有 suffixIcon 的 textField,但单击该图标后,我不需要打开键盘。如果没有 suffixIcon,我该如何做呢?
【问题讨论】:
令人困惑。你想要一个带有后缀图标的文本字段吗?您想为后缀图标添加功能(使其可点击..)吗?您希望文本字段可聚焦吗? 我想要 TextField 内的可点击图标,但是当我点击它时不显示键盘。TextField
具有readOnly
属性,如果设置为true
,则不会显示键盘。
那么我将无法将一些数据放入 textField。我想如果我点击文本字段写一些文本,但如果我点击 suffixIcon 不显示键盘并执行一些操作
【参考方案1】:
Container(
child: Stack(
alignment: Alignment.centerRight,
children: <Widget>[
TextField(),
IconButton(
icon: Icon(Icons.image),
onPressed: ()
// do something
,
),
],
),
)
【讨论】:
当TextField下方出现错误时,此解决方案不起作用,它使按钮不再垂直居中【参考方案2】:经过测试和确认,正是您想要的。
Stack(
alignment: Alignment.centerRight,
children: <Widget>[
TextField(
keyboardType: TextInputType.text,
style: Theme.of(context).textTheme.body1,
obscureText: true,
decoration: InputDecoration(
labelText: 'Password',
contentPadding: const EdgeInsets.fromLTRB(6, 6, 48, 6), // 48 -> icon width
),
),
IconButton(
icon: Icon(Icons.dialpad, color: const Color(0xfff96800)),
onPressed: ()
FocusScope.of(context).requestFocus(FocusNode());
// Your codes...
,
),
],
),
【讨论】:
【参考方案3】:这个问题还有一个可能的解决方法 - 取自这里:https://github.com/flutter/flutter/issues/39376 - 使用标准的 TextField 和一个按钮作为 suffixIcon,然后,魔术技巧:
InputDecoration(labelText: "Email address",
border: OutlineInputBorder(),
suffixIcon: IconButton(
iconSize: 40,
icon: Icon(Icons.fingerprint),
onPressed: () async
focusNode.unfocus();
focusNode.canRequestFocus = false;
await performBiometricLogin();
focusNode.canRequestFocus = true;
,
),
),
在这种情况下您必须注意两件事:
a) 在你的小部件中声明 focusNode(我在我的 statefull 小部件的状态类中这样做),然后将它用于你的文本字段:
FocusNode focusNode = FocusNode();
并在 TextField 中使用名为 focusNode 的属性:
focusNode: focusNode,
b) 如果您没有在 onPressed 事件处理程序中执行任何异步操作,那么您必须完全遵循 github 问题中的逻辑 - 一段时间后启用 canRequestFocus:
Future.delayed(Duration(milliseconds: 100), ()
widget.textFieldFocusNode.canRequestFocus = true;
);
希望它能像帮助我一样帮助其他人。
谢谢。
【讨论】:
这很完美,无需堆栈即可保持 TextField 的清洁。我添加了一件事,因为如果 textField 被聚焦并且 suffixIcon 被点击,我不想失去焦点。在点击处理程序中添加 """if (textFieldFocusNode.hasPrimaryFocus) return;"""" 完成了这项工作。完整答案在这里***.com/questions/49125064/…【参考方案4】:使用readOnly
,不要使用enabled
。
【讨论】:
【参考方案5】:单击而不打开键盘?如果是这样,只需创建一个类并将其分配给focusNode
,将hasFocus
设置为false
,如下所示:
class AlwaysDisabledFocusNode extends FocusNode
@override
bool get hasFocus => false;
new TextField(
focusNode: AlwaysDisabledFocusNode(),
onTap: () ,
keyboardType: TextInputType.text,
decoration: InputDecoration(
border: InputBorder.none,
icon: Icon(Icons.apps),
hintText: 'Password'),
style: Theme.of(context).textTheme.body1,
),
readOnly: true
会在点击时更改图标颜色
new TextField(readOnly: true,
//focusNode: AlwaysDisabledFocusNode(),
onTap: () ,
keyboardType: TextInputType.text,
decoration: InputDecoration(
border: InputBorder.none,
icon: Icon(Icons.apps),
hintText: 'Password'),
style: Theme.of(context).textTheme.body1,
),
我认为您必须将Row
与TextField
和IconButton
放在一起,并使用单独的操作。
new Row(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
new Expanded(
child: Padding(
child: new TextField(
onTap: () //action of TextField
,
keyboardType: TextInputType.text,
decoration: InputDecoration(
border: InputBorder.none, hintText: 'Password'),
style: Theme.of(context).textTheme.body1,
),
padding: EdgeInsets.only(left: 40),
)),
IconButton(
icon: Icon(Icons.apps),
onPressed: () //action of iconbutton
,
)
],
)
【讨论】:
我想如果我点击文本字段写一些文本,但如果我点击 suffixIcon 不显示键盘并执行一些操作 当您单击 textField 和单击图标时,您在两个选项中都有键盘。只有当我点击 textField 时我才需要键盘【参考方案6】:我也做到了
Container(
height: 40,
child: Stack(
children: <Widget>[
TextField(
controller: textEditingController,
keyboardType: TextInputType.text,
decoration: InputDecoration(
prefixIcon: Icon(HelageeIcons.search_icon_of_search_box),
border: OutlineInputBorder(
borderSide: BorderSide(
color: Color(0xff575656),
),
borderRadius: const BorderRadius.all(
const Radius.circular(50.0),
),
),
hintStyle:
TextStyle(color: Color(0xffADADAC), fontSize: 14),
hintText: "Quick Search",
),
),
Positioned(
right: 0,
child: Container(
height: 40,
width: 40,
child: Container(
child: Material(
shape: CircleBorder(),
color: Colors.transparent,
child: InkWell(
customBorder: CircleBorder(),
onTap: () ,
splashColor: Colors.grey,
child: Icon(Icons.keyboard))),
),
),
),
],
),
),
【讨论】:
【参考方案7】:添加后缀图标和后缀图标点击文本字段,在我的情况下我使用如下
TextFormField(
textInputAction: TextInputAction.done,
maxLines: 1,
obscureText: _obscureText,
autofocus: false,
focusNode: _passwordFocus,
style: TextStyle(fontSize: 17.0, color: Colors.black),
onFieldSubmitted: (term)
_passwordFocus.unfocus();
_validateAndSubmit();
,
decoration: InputDecoration(
hintText: HINT_PASSWORD,
hintStyle: TextStyle(fontSize: 17.0, color: Colors.black54),
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(color: Colors.black),
),
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(color: Colors.black87),
),
errorBorder: OutlineInputBorder(
borderSide: BorderSide(color: Colors.red),
),
disabledBorder: OutlineInputBorder(
borderSide: BorderSide(color: Colors.black87),
),
focusedErrorBorder: OutlineInputBorder(
borderSide: BorderSide(color: Colors.red),
),
labelText: HINT_PASSWORD,
labelStyle: TextStyle(fontSize: 17.0, color: Colors.black),
errorStyle: TextStyle(fontSize: 12.0, color: Colors.red),
prefixIcon: Icon(
Icons.lock,
color: themeColor,
),
/// magic is here suffix ixon click
suffixIcon: IconButton(
icon: Icon(
// Based on passwordVisible state choose the icon
_obscureText ? Icons.visibility : Icons.visibility_off,
color: themeColor,
),
onPressed: ()
// Update the state i.e. toogle the state of passwordVisible variable
setState(()
_obscureText ? _obscureText = false : _obscureText = true;
);
,
),
),
validator: validatePassword,
onSaved: (value) => _password = value,
)
【讨论】:
单击 suffixIcon 时您有活动键盘。它对我无效。【参考方案8】:这应该可以工作
Stack(
alignment: Alignment.centerRight,
children: <Widget>[
TextFormField(
),
FlatButton(
onPressed: ()
_openOrhidePassword();
,
child: Image(
height: 24.0,
width: 24.0,
image: AssetImage('images/Eye.png'),
),
),
],
),
在我的情况下,图像大小是另一个问题。当我提供尺寸时,它可以很好地与其他小部件一起使用。
【讨论】:
以上是关于TextFormField 上的可点击图标 - 禁用 TextFormField 对图标单击的关注(颤振)的主要内容,如果未能解决你的问题,请参考以下文章
fullcalendar 为放置在事件上的可点击图标取消绑定 eventClick 方法
如何在TextFormField下方的errorText中添加图标?
如何在TextFormField的hintText中添加图标