我正在开发 Flutter 应用程序,但 ElevatedButton 的位置有问题。当 Validator 在 TextFormField 下方返回错误信息时,widget 向下展开,添加按钮的位置发生变化。我想将添加按钮固定在与应用程序开头相同的位置
Button out of its original position after returning the validator
我的代码:
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Lista de Compras"),
backgroundColor: Colors.green,
centerTitle: true,
),
body: Column(
children: <Widget>[
Container(
padding: EdgeInsets.fromLTRB(15, 10, 5, 10),
child: Form(
key: _formKey,
child: Row(
children: <Widget>[
Theme(
data: ThemeData(
primaryColor: Colors.green,
hintColor: Colors.green),
child: Expanded(
child: TextFormField(
controller: _controlador,
validator: (value) {
if (value.isEmpty) {
return "Insira um item";
}
return null;
},
decoration: InputDecoration(
enabledBorder: OutlineInputBorder(
borderSide:
BorderSide(color: Colors.green),
borderRadius:
BorderRadius.circular(100)),
border: OutlineInputBorder(
borderRadius:
BorderRadius.circular(100)),
labelText: "Novo item",
hintText: "Insira um item",
hintStyle: TextStyle(color: Colors.grey),
labelStyle:
TextStyle(color: Colors.green),
suffixIcon: IconButton(
onPressed: () => _controlador.clear(),
icon: Icon(Icons.clear,
color: Colors.grey),
))))),
Padding(padding: EdgeInsets.only(right: 6)),
ElevatedButton(
style: ElevatedButton.styleFrom(
primary: Colors.green,
shape: CircleBorder(),
padding: EdgeInsets.all(12)),
child: Icon(Icons.add, color: Colors.white),
onPressed: () {
if (_formKey.currentState.validate()) {
_addCompras();
}
}),
],
),
)),
答案 0 :(得分:1)
这是预期的行为,当 TextFormField
显示 errorText
时,这将在 TextFormField
下方附加一个文本,增加大约 22 的额外高度。检查下面的工作示例:
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData.light(),
debugShowCheckedModeBanner: false,
home: Scaffold(
body: Column(
children: [
MeasureSize(
child: FormWidget(),
onChange: (size) {
print(size);
},
),
MeasureSize(
child: FormWidget(hideError: false),
onChange: (size) {
print(size);
},
),
FormWidget(
hideError: false,
addPaddingToTrailingButton: true,
),
],
),
),
);
}
}
class FormWidget extends StatelessWidget {
final bool hideError;
final bool addPaddingToTrailingButton;
FormWidget({
this.hideError = true,
this.addPaddingToTrailingButton = false,
});
@override
Widget build(BuildContext context) {
Widget trailingButton = ElevatedButton(
style: ElevatedButton.styleFrom(
shape: CircleBorder(),
padding: EdgeInsets.all(12),
),
child: Icon(Icons.add),
onPressed: () {},
);
if (addPaddingToTrailingButton) {
trailingButton = Padding(
padding: const EdgeInsets.only(bottom: 22),
child: trailingButton,
);
}
return Container(
color: Colors.grey[300],
margin: const EdgeInsets.symmetric(vertical: 16),
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
SizedBox(width: 8),
Expanded(
child: TextField(
decoration: InputDecoration(
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(100),
),
labelText: "Label text field",
hintText: "Hint text field",
errorText: hideError ? null : 'Error text shown',
suffixIcon: IconButton(
onPressed: () {},
icon: Icon(Icons.clear),
),
),
),
),
SizedBox(width: 8),
trailingButton,
],
),
);
}
}
typedef void OnWidgetSizeChange(Size size);
class MeasureSizeRenderObject extends RenderProxyBox {
Size oldSize;
final OnWidgetSizeChange onChange;
MeasureSizeRenderObject(this.onChange);
@override
void performLayout() {
super.performLayout();
Size newSize = child.size;
if (oldSize == newSize) return;
oldSize = newSize;
WidgetsBinding.instance.addPostFrameCallback((_) {
onChange(newSize);
});
}
}
class MeasureSize extends SingleChildRenderObjectWidget {
final OnWidgetSizeChange onChange;
const MeasureSize({
Key key,
@required this.onChange,
@required Widget child,
}) : super(key: key, child: child);
@override
RenderObject createRenderObject(BuildContext context) {
return MeasureSizeRenderObject(onChange);
}
}
答案 1 :(得分:0)
Allan 上面的回答非常好。 但是,如果您在学习时遇到问题,请这样做:
Column(
children: [
ElevatedButton(...),
SizedBox(
height: 22,
),
],
),
helperText: ' ',
:TextFormField(
validator: (value) {
if (value == null || value.isEmpty) {
return "Insira um item";
}
return null;
},
decoration: InputDecoration(
helperText: ' ',
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(color: Colors.green),
borderRadius: BorderRadius.circular(100)),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(100)),
labelText: "Novo item",
hintText: "Insira um item",
hintStyle: TextStyle(color: Colors.grey),
labelStyle: TextStyle(color: Colors.green),
),
),
Here 你可以看到完整代码的飞镖板。