好吧,这有点难以解释。
我想要两个文本字段位于彼此的上方/下方。当您在其中一个文本字段中输入内容并且结果应显示在其他内容上方的可变大小容器中而不将其他内容向下推时,问题就出现了。
我可以只使用带有定位的堆栈,但是由于设备上的屏幕尺寸、字体和文本大小不同,我在精确定位方面遇到了问题。如果我使用列,内容就会被下推。
查看屏幕截图以帮助理解我的问题(代码如下)
这对于所有屏幕/尺寸/字体/等来说应该是这样的。 我可以使用 Stack+Positioned 得到这个结果,但我可以进一步说明问题。 (红色框是可变大小的结果容器)。
这就是当我使用 Stack+Positioned 并且手机上的文本大小增加(或字体不同,或其他类似的情况)时发生的情况。
这就是我将文本字段放入列中时发生的情况。
代码
这显然只是示例代码。在真实的应用程序中,我们有两个地址搜索,它们调用 API 来获取结果列表。
class StackProblemExample extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Stack(
children: [
Positioned(
top: 82,
left: 0,
right: 0,
child: TextFieldAndResultList(
hint: 'To',
isTop: false,
),
),
Positioned(
top: 20,
left: 0,
right: 0,
child: TextFieldAndResultList(
hint: 'From',
isTop: true,
),
),
],
);
}
}
class TextFieldAndResultList extends StatefulWidget {
final String hint;
final bool isTop;
const TextFieldAndResultList({
super.key,
required this.hint,
required this.isTop,
});
@override
State<TextFieldAndResultList> createState() => _TextFieldAndResultListState();
}
class _TextFieldAndResultListState extends State<TextFieldAndResultList> {
var controller = TextEditingController();
var containerHeight = 0;
@override
Widget build(BuildContext context) {
return Column(
children: [
TextField(
decoration: InputDecoration(
hintText: widget.hint,
border: OutlineInputBorder(
borderRadius: widget.isTop
? BorderRadius.only(
topLeft: Radius.circular(10),
topRight: Radius.circular(10),
)
: BorderRadius.only(
bottomLeft: Radius.circular(10),
bottomRight: Radius.circular(10),
),
),
),
controller: controller,
onChanged: (value) {
setState(() {
containerHeight = controller.text.length * 10;
});
},
),
if (containerHeight > 0)
Container(
height: containerHeight.toDouble(),
color: Colors.red,
),
],
);
}
}
我到底如何才能实现两个 TextFields(每个都有自己的结果容器)可以在没有具体位置的情况下彼此堆叠并且不会相互推倒?
使用自动完成,它的设计正是为了做到这一点。
一个小部件,用于帮助用户通过输入一些文本并从选项列表中进行选择来进行选择。
Autocomplete<String>(
fieldViewBuilder: (BuildContext context,
TextEditingController fieldTextEditingController,
FocusNode fieldFocusNode,
VoidCallback onFieldSubmitted) {
return TextFormField(
decoration: InputDecoration(
...
),
controller: fieldTextEditingController,
focusNode: fieldFocusNode,
);
},
optionsBuilder: (TextEditingValue textEditingValue) {
...
},
onSelected: (String selection) {
...
},
);