I’m trying to make TextFormField widget change its height depending on the window height at the moment.
I’ve wrapped TextFormField with ConstrainedBox, which changes height constraints to the desired value. In the TextFormField widget I change its height using contentPadding.
If i’m using some finite number in vertical padding for contentPadding, larger than desired height, everything works and TextFormField changes its size, but if i use double.infinity, flutter throws following exception:
<code>[ERROR:flutter/flow/layers/transform_layer.cc(23)] TransformLayer is constructed with an invalid matrix.
══╡ EXCEPTION CAUGHT BY GESTURES LIBRARY ╞══════════════════════════════════════════════════════════
The following assertion was thrown while handling a pointer data packet:
'package:flutter/src/material/input_decorator.dart': Failed assertion: line 1636 pos 18:
'transformed == position - offset': is not true.
</code>
<code>[ERROR:flutter/flow/layers/transform_layer.cc(23)] TransformLayer is constructed with an invalid matrix.
══╡ EXCEPTION CAUGHT BY GESTURES LIBRARY ╞══════════════════════════════════════════════════════════
The following assertion was thrown while handling a pointer data packet:
'package:flutter/src/material/input_decorator.dart': Failed assertion: line 1636 pos 18:
'transformed == position - offset': is not true.
</code>
[ERROR:flutter/flow/layers/transform_layer.cc(23)] TransformLayer is constructed with an invalid matrix.
══╡ EXCEPTION CAUGHT BY GESTURES LIBRARY ╞══════════════════════════════════════════════════════════
The following assertion was thrown while handling a pointer data packet:
'package:flutter/src/material/input_decorator.dart': Failed assertion: line 1636 pos 18:
'transformed == position - offset': is not true.
My TextFormField code:
<code>import 'package:flutter/material.dart';
class HeliosFormTextField extends StatefulWidget {
const HeliosFormTextField({
super.key,
required this.controller,
required this.labelText,
required this.labelTextOnError,
required this.validityCriteria,
this.keyboardType,
this.obscureText = false,
this.clearOnError = true,
});
final TextEditingController controller;
final String labelText;
final String labelTextOnError;
final bool Function(String?) validityCriteria;
final bool obscureText;
final bool clearOnError;
final TextInputType? keyboardType;
@override
State<HeliosFormTextField> createState() => _HeliosFormTextFieldState();
}
class _HeliosFormTextFieldState extends State<HeliosFormTextField> {
TextFieldStatus status = TextFieldStatus.none;
///Can change behaviour of the widget only if [widget.obscureText] is true
bool obscureSymbols = true;
@override
Widget build(BuildContext context) {
return ConstrainedBox(
constraints: BoxConstraints.tightFor(height: MediaQuery.of(context).size.height * 0.065,),
child: TextFormField(
cursorErrorColor: Theme.of(context).colorScheme.primary,
obscureText: widget.obscureText ? obscureSymbols : false,
style: Theme.of(context)
.textTheme
.bodyMedium
?.copyWith(fontWeight: FontWeight.w500),
keyboardType: widget.keyboardType,
autocorrect: false,
decoration: InputDecoration(
labelText: status == TextFieldStatus.error ? widget.labelTextOnError : widget.labelText,
labelStyle: status == TextFieldStatus.error ? Theme.of(context).textTheme.bodyMedium?.copyWith(color: Colors.red) : Theme.of(context).textTheme.bodyMedium ,
border: const OutlineInputBorder(borderRadius: BorderRadius.all(Radius.circular(20)), borderSide: BorderSide.none),
floatingLabelBehavior: FloatingLabelBehavior.never,
filled: true,
fillColor: Theme.of(context).colorScheme.surface,
errorStyle: const TextStyle(
height: 0,
color: Colors.transparent,
),
isDense: true,
contentPadding: const EdgeInsets.symmetric(horizontal: 20, vertical: 1000), //If i were to put double.infinity instead 1000 the exception would trigger
suffixIcon: widget.obscureText ?
IconButton(
icon: Icon(obscureSymbols ? Icons.visibility_rounded : Icons.visibility_off_rounded),
onPressed: () => setState(() {
obscureSymbols = !obscureSymbols;
}),
)
: null,
),
controller: widget.controller,
validator: (value) {
if (!widget.validityCriteria(value)) {
if (status != TextFieldStatus.error) {
setState(() {
status = TextFieldStatus.error;
});
if (widget.clearOnError) widget.controller.clear();
}
return '';
}
return null;
},
onChanged: (value) {
if (status == TextFieldStatus.error &&
widget.validityCriteria(value)) {
setState(() {
status = TextFieldStatus.none;
});
}
},
),
);
}
}
enum TextFieldStatus {
none,
error,
selected,
}
</code>
<code>import 'package:flutter/material.dart';
class HeliosFormTextField extends StatefulWidget {
const HeliosFormTextField({
super.key,
required this.controller,
required this.labelText,
required this.labelTextOnError,
required this.validityCriteria,
this.keyboardType,
this.obscureText = false,
this.clearOnError = true,
});
final TextEditingController controller;
final String labelText;
final String labelTextOnError;
final bool Function(String?) validityCriteria;
final bool obscureText;
final bool clearOnError;
final TextInputType? keyboardType;
@override
State<HeliosFormTextField> createState() => _HeliosFormTextFieldState();
}
class _HeliosFormTextFieldState extends State<HeliosFormTextField> {
TextFieldStatus status = TextFieldStatus.none;
///Can change behaviour of the widget only if [widget.obscureText] is true
bool obscureSymbols = true;
@override
Widget build(BuildContext context) {
return ConstrainedBox(
constraints: BoxConstraints.tightFor(height: MediaQuery.of(context).size.height * 0.065,),
child: TextFormField(
cursorErrorColor: Theme.of(context).colorScheme.primary,
obscureText: widget.obscureText ? obscureSymbols : false,
style: Theme.of(context)
.textTheme
.bodyMedium
?.copyWith(fontWeight: FontWeight.w500),
keyboardType: widget.keyboardType,
autocorrect: false,
decoration: InputDecoration(
labelText: status == TextFieldStatus.error ? widget.labelTextOnError : widget.labelText,
labelStyle: status == TextFieldStatus.error ? Theme.of(context).textTheme.bodyMedium?.copyWith(color: Colors.red) : Theme.of(context).textTheme.bodyMedium ,
border: const OutlineInputBorder(borderRadius: BorderRadius.all(Radius.circular(20)), borderSide: BorderSide.none),
floatingLabelBehavior: FloatingLabelBehavior.never,
filled: true,
fillColor: Theme.of(context).colorScheme.surface,
errorStyle: const TextStyle(
height: 0,
color: Colors.transparent,
),
isDense: true,
contentPadding: const EdgeInsets.symmetric(horizontal: 20, vertical: 1000), //If i were to put double.infinity instead 1000 the exception would trigger
suffixIcon: widget.obscureText ?
IconButton(
icon: Icon(obscureSymbols ? Icons.visibility_rounded : Icons.visibility_off_rounded),
onPressed: () => setState(() {
obscureSymbols = !obscureSymbols;
}),
)
: null,
),
controller: widget.controller,
validator: (value) {
if (!widget.validityCriteria(value)) {
if (status != TextFieldStatus.error) {
setState(() {
status = TextFieldStatus.error;
});
if (widget.clearOnError) widget.controller.clear();
}
return '';
}
return null;
},
onChanged: (value) {
if (status == TextFieldStatus.error &&
widget.validityCriteria(value)) {
setState(() {
status = TextFieldStatus.none;
});
}
},
),
);
}
}
enum TextFieldStatus {
none,
error,
selected,
}
</code>
import 'package:flutter/material.dart';
class HeliosFormTextField extends StatefulWidget {
const HeliosFormTextField({
super.key,
required this.controller,
required this.labelText,
required this.labelTextOnError,
required this.validityCriteria,
this.keyboardType,
this.obscureText = false,
this.clearOnError = true,
});
final TextEditingController controller;
final String labelText;
final String labelTextOnError;
final bool Function(String?) validityCriteria;
final bool obscureText;
final bool clearOnError;
final TextInputType? keyboardType;
@override
State<HeliosFormTextField> createState() => _HeliosFormTextFieldState();
}
class _HeliosFormTextFieldState extends State<HeliosFormTextField> {
TextFieldStatus status = TextFieldStatus.none;
///Can change behaviour of the widget only if [widget.obscureText] is true
bool obscureSymbols = true;
@override
Widget build(BuildContext context) {
return ConstrainedBox(
constraints: BoxConstraints.tightFor(height: MediaQuery.of(context).size.height * 0.065,),
child: TextFormField(
cursorErrorColor: Theme.of(context).colorScheme.primary,
obscureText: widget.obscureText ? obscureSymbols : false,
style: Theme.of(context)
.textTheme
.bodyMedium
?.copyWith(fontWeight: FontWeight.w500),
keyboardType: widget.keyboardType,
autocorrect: false,
decoration: InputDecoration(
labelText: status == TextFieldStatus.error ? widget.labelTextOnError : widget.labelText,
labelStyle: status == TextFieldStatus.error ? Theme.of(context).textTheme.bodyMedium?.copyWith(color: Colors.red) : Theme.of(context).textTheme.bodyMedium ,
border: const OutlineInputBorder(borderRadius: BorderRadius.all(Radius.circular(20)), borderSide: BorderSide.none),
floatingLabelBehavior: FloatingLabelBehavior.never,
filled: true,
fillColor: Theme.of(context).colorScheme.surface,
errorStyle: const TextStyle(
height: 0,
color: Colors.transparent,
),
isDense: true,
contentPadding: const EdgeInsets.symmetric(horizontal: 20, vertical: 1000), //If i were to put double.infinity instead 1000 the exception would trigger
suffixIcon: widget.obscureText ?
IconButton(
icon: Icon(obscureSymbols ? Icons.visibility_rounded : Icons.visibility_off_rounded),
onPressed: () => setState(() {
obscureSymbols = !obscureSymbols;
}),
)
: null,
),
controller: widget.controller,
validator: (value) {
if (!widget.validityCriteria(value)) {
if (status != TextFieldStatus.error) {
setState(() {
status = TextFieldStatus.error;
});
if (widget.clearOnError) widget.controller.clear();
}
return '';
}
return null;
},
onChanged: (value) {
if (status == TextFieldStatus.error &&
widget.validityCriteria(value)) {
setState(() {
status = TextFieldStatus.none;
});
}
},
),
);
}
}
enum TextFieldStatus {
none,
error,
selected,
}
Really hoping for your help