问题描述
我会链接以创建一个缩小到内部文本的 TextField
。
为此,我使用了 this answer 表示使用 IntrinsicWidth
小部件。
它运行良好,但如果我指定 hintText
,即使用户输入非常短的文本,TextField
的宽度也不会小于 hintText
的宽度。
这是一个例子:
import 'package:Flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: Center(
child: Container(
alignment: Alignment.center,height: 50,width: 300,child: Container(
alignment: Alignment.center,padding: EdgeInsets.all(10),color: Colors.grey[100],child: IntrinsicWidth(
child: TextField(
decoration: Inputdecoration(
hintText: 'My very very long hint',// Remove it and the text field can be as small as the text inside
),),);
}
}
text field的宽度就是里面文字的宽度,这就是我想要的。 ✔️
这是带有提示的空字段:
没有文字的时候,text field的宽度就是hint的宽度,这就是我想要的。 ✔️
字段的宽度就是里面文字的宽度,这就是我想要的。 ✔️
正如你所看到的,字段宽度是提示的宽度,而不是里面的文本(这不是我想要的❌)。
如何强制它是内部实际文本的宽度?
解决方法
您可以根据 hintText
的内容有条件地更改 TextEditingController
:
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
void main() => runApp(MyApp());
class MyApp extends HookWidget {
@override
Widget build(BuildContext context) {
final _controller = useTextEditingController();
final _editing = useState(false);
_controller.addListener(() => _editing.value = _controller.text.isNotEmpty);
return MaterialApp(
home: Scaffold(
body: Center(
child: Container(
alignment: Alignment.center,width: 300,child: Container(
alignment: Alignment.center,padding: EdgeInsets.all(10),color: Colors.grey[100],child: Column(
children: [
IntrinsicWidth(
child: TextFormField(
controller: _controller,decoration: InputDecoration(
hintText: _editing.value
? '' // empty hintText if field is not empty
: 'My very very long hint',),],);
}
}
,
1.将字段宽度设置为文本的宽度而不是提示
这可以通过使用 TextField 小部件中的 onChanged() 函数实现,如下所示。
为了能够使用 setState,MyApp 类需要是一个 StatefulWidget。
onChanged: (value) => {
if (value.isNotEmpty) {
setState(() {
hText = '';
})
} else {
setState(() {
hText = 'My very very long hint';
})
}
}
2.包装 TextField 的两个容器
我注意到尽管使用了 IntrinsicWidth,但两个容器限制了 TextField 的大小。
如果您使用容器来设置 TextField 可见,另一种方法是设置 TextField 的边框。
Scaffold 的主体可能如下所示:
Center(
child: IntrinsicWidth(
child: TextField(
onChanged: (value) => {
if (value.isNotEmpty) {
setState(() {
hText = '';
})
} else {
setState(() {
hText = 'My very very long hint';
})
}
},decoration: InputDecoration(
enabledBorder: UnderlineInputBorder(
borderSide: BorderSide(color: Colors.black),focusedBorder: UnderlineInputBorder(
borderSide: BorderSide(color: Colors.teal),hintText:
hText,// Remove it and the text field can be as small as the text inside
),)
完整代码
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
String hText = 'My very very long hint';
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: Center(
child: IntrinsicWidth(
child: TextField(
onChanged: (value) => {
if (value.isNotEmpty)
{
setState(() {
hText = '';
})
}
else
{
setState(() {
hText = 'My very very long hint';
})
}
},decoration: InputDecoration(
enabledBorder: UnderlineInputBorder(
borderSide: BorderSide(color: Colors.black),//When the TextFormField is ON focus
focusedBorder: UnderlineInputBorder(
borderSide: BorderSide(color: Colors.teal),hintText:
hText,// Remove it and the text field can be as small as the text inside
),);
}
}