I made a TextField builder and customized it and added a shadow to it using "Material" widget And when an error message is shown to the user in the app the TextField gets pushed up but the shadow itself stays Where it was (code and picture included below)
import 'package:flutter/material.dart';
import 'constants.dart';
class TextFieldBuilder extends StatefulWidget {
TextFieldBuilder({
Key key,
this.icon,
this.hint,
this.obscure,
this.height,
this.fontSize,
this.iconSize,
this.fillColor,
this.hintFontSize,
this.iconColor,
this.validatorFunction,
this.textInputType,
this.initialValue,
this.onSavedFunc,
}) : super(key: key);
final IconData icon;
final String hint;
final bool obscure;
final height, fontSize, iconSize, fillColor, hintFontSize;
final iconColor;
final validatorFunction;
final textInputType;
final initialValue;
final onSavedFunc;
@override
_TextFieldBuilderState createState() => _TextFieldBuilderState();
}
class _TextFieldBuilderState extends State<TextFieldBuilder> {
var _data;
@override
Widget build(BuildContext context) {
return Container(
child: Material(
color: Colors.transparent,
borderRadius: BorderRadius.circular(9),
child: Container(
decoration:
BoxDecoration(borderRadius: BorderRadius.circular(9), boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(0.15),
blurRadius: 4,
offset: Offset(1, 3),
)
]),
child: TextFormField(
autovalidateMode: AutovalidateMode.onUserInteraction,
initialValue: widget.initialValue ?? null,
keyboardType: widget.textInputType ?? null,
onSaved: widget.onSavedFunc ??
(String value) {
_data = value.trim();
if (widget.hint != password &&
widget.hint != 'Confirm Password') {
print('${widget.hint} is $_data');
}
},
validator: widget.validatorFunction,
style: TextStyle(
color: Color(textColor),
fontSize: widget.fontSize ?? 18,
),
obscureText: widget.obscure ?? false,
decoration: InputDecoration(
contentPadding: EdgeInsets.symmetric(vertical: 1.0),
prefixIcon: Icon(
widget.icon ?? Icons.error,
size: widget.iconSize ?? 35,
color: widget.iconColor ?? Color(iconColor),
),
filled: true,
fillColor: Color(textFieldColor),
hintText: widget.hint ?? placeholder,
hintStyle: TextStyle(
color: Color(textColor),
fontSize: widget.fontSize ?? 18,
height: widget.height ?? 0.9,
),
border: OutlineInputBorder(
borderSide: BorderSide.none,
borderRadius: BorderRadius.circular(9),
),
focusColor: Color(textFieldColor),
),
),
),
),
);
}
}
I tried wrapping both widgets with a container but it did not seem to help
Combine your TextField
with a Text
and place both inside a Column
. You will be able to replicate the error display without messing up the shadow. Remember to hide the default error message as well.
You can use the elevation
and shadowColor
property of Material
to save some code lines btw. Something like:
Material(
color: Colors.transparent,
borderRadius: BorderRadius.circular(9),
elevation: 4,
shadowColor: Colors.black.withOpacity(0.15),
// ... other lines
);
Example code:
// ... other lines
class _TextFieldBuilderState extends State<TextFieldBuilder> {
var _data;
String _errorText = '';
@override
Widget build(BuildContext context) {
return Container(
//!! Place both Widgets inside a Column
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Material(
color: Colors.transparent,
borderRadius: BorderRadius.circular(9),
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(9),
boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(0.15),
blurRadius: 4,
offset: Offset(1, 3),
)
]),
child: TextFormField(
autovalidateMode: AutovalidateMode.onUserInteraction,
initialValue: widget.initialValue ?? null,
keyboardType: widget.textInputType ?? null,
onSaved: widget.onSavedFunc ??
(String value) {
_data = value.trim();
if (widget.hint != password &&
widget.hint != 'Confirm Password') {
print('${widget.hint} is $_data');
}
},
//!! Set the errorText value here, the Future delayed is to avoid calling [setState] during [build]
validator: (value) {
Future.delayed(Duration.zero, () {
// calling [setState] during [build]
setState(() {
_errorText = widget.validatorFunction(value) ?? '';
});
});
return _errorText;
},
style: TextStyle(
color: Color(textColor),
fontSize: widget.fontSize ?? 18,
),
obscureText: widget.obscure ?? false,
decoration: InputDecoration(
contentPadding: EdgeInsets.symmetric(vertical: 1.0),
prefixIcon: Icon(
widget.icon ?? Icons.error,
size: widget.iconSize ?? 35,
color: widget.iconColor ?? Color(iconColor),
),
filled: true,
fillColor: Color(textFieldColor),
//!! Hide the default error message here
errorStyle: TextStyle(fontSize: 0),
hintText: widget.hint ?? placeholder,
hintStyle: TextStyle(
color: Color(textColor),
fontSize: widget.fontSize ?? 18,
height: widget.height ?? 0.9,
),
border: OutlineInputBorder(
borderSide: BorderSide.none,
borderRadius: BorderRadius.circular(9),
),
focusColor: Color(textFieldColor),
),
),
),
),
//!! Display the error message here
if (_errorText.isNotEmpty)
Text(
_errorText,
style: TextStyle(color: Colors.red),
)
],
),
);
}
}
and show the error message in another widget
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.