我有一个TextField,它有一个属性prefixIcon,它接受一个小部件。我通过了一个GestureDetector,这样我就可以对它做一些onTap事件。但是我所面临的问题是,我一点击它,它就把它称为onTap事件,但同时它也聚焦了进一步启动键盘的TextField。
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body:MyWidget,
);
}
}
class MyWidget extends StatefulWidget{
@override
State<StatefulWidget> createState() {
return MyWidgetState();
}
}
class MyWidgetState extends State<MyWidget>
{
@override
Widget build(BuildContext context) {
return Container(
height: 200,
width: 200,
padding: EdgeInsets.all(20),
child: TextField(
decoration: InputDecoration(
prefixIcon: GestureDetector(
child: Container(color: Colors.greenAccent, width: 25, height: 25,),
onTap: () => print("hmm"),
),
),
),
);
}
}因此,我试图找到一种方法来点击prefixIcon小部件(在这里,GestureDetector不聚焦TextField)。我如何实现这一功能?
发布于 2019-10-17 01:01:25
我面临着一个类似的问题,这里我解释了这个问题和一个可能的解决方案:Flutter DropdownButton inside TextFormField as prefix
在您的例子中,DropdownButton是一个Container,所以您可以这样做:
Wrap(
children: <Widget>[
Container(
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(16.0),
boxShadow: [BoxShadow()],
),
child: Row(
children: <Widget>[
GestureDetector(
child: Container(color: Colors.greenAccent, width: 25, height: 25,),
onTap: () => print("hmm"),
),
Flexible(
child: TextField(),
),
],
),
),
],
)编辑:不幸的是, TextField的prefix是打算在TextField聚焦时使用的。我可以想出一个解决办法,检测TextField的焦点,并在prefix被点击时不对焦,下面是一个例子:
final _controller = TextEditingController(text: "Test");
final _focusNode = FocusNode();
var _prefixTapped = false;
@override
void initState() {
super.initState();
_focusNode.addListener(() {
if (_focusNode.hasFocus & _prefixTapped) _focusNode.unfocus();
_prefixTapped = false;
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text("TextFieldWithGesturePrefix")),
body: TextField(
controller: _controller,
focusNode: _focusNode,
decoration: InputDecoration(
prefixIcon: GestureDetector(
child: Container(
color: Colors.greenAccent,
child: Text("Any widget"),
),
onTap: () {
_prefixTapped = true;
_focusNode.unfocus();
print("prefix tapped");
},
),
),
),
);
}发布于 2019-10-16 22:44:03
您可以将TextField包装在行中,然后在此之前添加一个可点击的图标。那么,默认行为是什么就不重要了。
Container(
height: 200,
width: 200,
padding: EdgeInsets.all(20),
child: Row(
children: <Widget>[
GestureDetector(
child: Container(color: Colors.greenAccent, width: 25, height: 25,),
onTap: () => print("hmm"),
),
Expanded(child: TextField()),
],
),
)我想我有一个更好的解决方案,因为它不需要对FocusNode进行任何操作。只需将两者传递到一个堆栈中,利用CompositedTransformTarget/关注者,并将装饰器与您想要的项覆盖起来。我已经测试过了,而且效果很好。它还使得您想要放置在前缀输入上的图标沿着文本字段的大小(如果这是您想要的内容)来显示。让一切保持同步。
class TestWidget extends StatelessWidget {
final LayerLink link = LayerLink();
@override
Widget build(BuildContext context) {
return Stack(
children: <Widget>[
TextField(
maxLines: null,
decoration: InputDecoration(
prefixIcon: CompositedTransformTarget(
child: Container(color: Colors.transparent, width: 25, height: 25,),
link: link,
),
)
),
CompositedTransformFollower(
link: link,
child: GestureDetector(
child: Container(color: Colors.greenAccent, width: 25, height: 25,),
onTap: () => Vibrate.feedback(FeedbackType.heavy),
),
)
],
);
}
}https://stackoverflow.com/questions/58422114
复制相似问题