I am trying to use DropdownButtonFormField in tab controller with tab viewer on flutter web. It is showing but not showing dropdown options on clicking on it showing an error please find below my code and error.
Below is my example code:
import 'package:flutter/material.dart';
class UserManager extends StatefulWidget {
const UserManager({Key? key}) : super(key: key);
#override
_UserManagerState createState() => _UserManagerState();
}
class _UserManagerState extends State<UserManager> {
final _formkey = GlobalKey<FormState>();
var addName = "";
var addEmail = "";
var addPassword = "";
var addRole = "";
final nameController = TextEditingController();
final emailController = TextEditingController();
final passwordController = TextEditingController();
final roleController = TextEditingController();
#override
Widget build(BuildContext context) {
return MaterialApp(
home: DefaultTabController(
length: 2,
child: Scaffold(
appBar: AppBar(
toolbarHeight: 20,
bottom: const TabBar(
tabs: [
Tab(icon: Icon(Icons.person_add)),
Tab(icon: Icon(Icons.edit)),
],
),
),
body: TabBarView(
children: [
Center(
child: Form(
key: _formkey,
child: SingleChildScrollView(
reverse: true,
child: Container(
width: 420,
margin: const EdgeInsets.all(10.0),
padding: const EdgeInsets.all(16),
decoration: BoxDecoration(
border: Border.all(color: Colors.grey),
borderRadius: const BorderRadius.all(
Radius.circular(10),
),
),
child: Column(
children: [
//const SizedBox(
//height: 50,
//),
const Text(
"Add name",
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold,
color: Colors.indigo,
),
),
const SizedBox(
height: 10,
),
TextFormField(
minLines: 1,
autofocus: false,
keyboardType: TextInputType.text,
textInputAction: TextInputAction.next,
decoration: const InputDecoration(
labelText: "Name",
border: OutlineInputBorder(),
errorStyle: TextStyle(
color: Colors.redAccent, fontSize: 15),
),
controller: nameController,
validator: (value) {
if (value == null || value.isEmpty) {
return 'Please Enter Name';
}
return null;
}),
const SizedBox(
height: 10,
),
TextFormField(
autofocus: false,
minLines: 1,
keyboardType: TextInputType.emailAddress,
textInputAction: TextInputAction.next,
decoration: const InputDecoration(
labelText: "Email Address",
//hintText: "Email",
border: OutlineInputBorder(),
errorStyle: TextStyle(
color: Colors.redAccent, fontSize: 15),
),
controller: emailController,
validator: (value) {
if (value == null || value.isEmpty) {
return 'Please Enter Email ID';
} else if (!value.contains('#')) {
return 'Please Enter Valid Email ID';
}
return null;
}),
const SizedBox(
height: 10,
),
TextFormField(
minLines: 1,
autofocus: false,
obscureText: true,
keyboardType: TextInputType.text,
textInputAction: TextInputAction.next,
decoration: const InputDecoration(
labelText: "Password",
border: OutlineInputBorder(),
errorStyle: TextStyle(
color: Colors.redAccent, fontSize: 15),
),
controller: passwordController,
validator: (value) {
if (value == null || value.isEmpty) {
return 'Please Enter Password';
}
return null;
}),
const SizedBox(
height: 20,
),
//
DropdownButtonFormField(
decoration: const InputDecoration(
labelText: "department",
border: OutlineInputBorder(),
errorStyle: TextStyle(
color: Colors.redAccent, fontSize: 15),
),
hint: const Text("select department"),
value: addRole,
onChanged: (String? newValue) {
setState(() {
addRole = newValue!;
});
},
validator: (value) => value == null ? 'field required' : null,
items: <String>[
'',
'hr',
'dtp'
].map<DropdownMenuItem<String>>((String value) {
return DropdownMenuItem<String>(
value: value,
child: Text(value),
);
}).toList(),
),
const SizedBox(
height: 20,
),
//
ElevatedButton(
style: ElevatedButton.styleFrom(
primary: Colors.red, // background
onPrimary: Colors.white, // foreground
),
onPressed: () {}
child: const Text('User Add'),
),
const SizedBox(
height: 20,
),
],
),
),
)),
),
Center(
child: Text("Test"),
)
],
),
),
),
);
}
}
Below is the error:
Exception has occurred. "Error: Cannot hit test a render box that has
never been laid out. The hitTest() method was called on this
RenderBox: RenderSemanticsAnnotations#119e3 NEEDS-LAYOUT NEEDS-PAINT:
needs compositing creator: Semantics ← _EffectiveTickerMode ←
TickerMode ←
_OverlayEntryWidget-[LabeledGlobalKey<_OverlayEntryWidgetState>#c466c] ← _Theatre ← Overlay-[LabeledGlobalKey#26f68] ←
UnmanagedRestorationScope ← _FocusMarker ← Semantics ← FocusScope ←
AbsorbPointer ← Listener ← ⋯ parentData: not positioned;
offset=Offset(0.0, 0.0) constraints: MISSING size: MISSING
Unfortunately, this object's geometry is not known at this time,
probably because it has never been laid out. This means it cannot be
accurately hit-tested. If you are trying to perform a hit test during
the layout phase itself, make sure you only hit test nodes that have
completed layout (e.g. the node's children, after their layout()
method has been called).
Debug console:
════════ Exception caught by rendering library ═════════════════════════════════
The following assertion was thrown during performLayout():
LayoutBuilder does not support returning intrinsic dimensions.
Calculating the intrinsic dimensions would require running the layout callback speculatively, which might mutate the live render object tree.
The relevant error-causing widget was
SliverFillRemaining
When the exception was thrown, this was the stack
The following RenderObject was being processed when the exception was fired: RenderSliverFillRemaining#ef0f7 relayoutBoundary=up1 NEEDS-LAYOUT NEEDS-COMPOSITING-BITS-UPDATE
RenderObject: RenderSliverFillRemaining#ef0f7 relayoutBoundary=up1 NEEDS-LAYOUT NEEDS-COMPOSITING-BITS-UPDATE
needs compositing
parentData: paintOffset=Offset(0.0, 0.0) (can use size)
constraints: SliverConstraints(AxisDirection.down, GrowthDirection.forward, ScrollDirection.idle, scrollOffset: 0.0, remainingPaintExtent: 574.0, crossAxisExtent: 1034.0, crossAxisDirection: AxisDirection.right, viewportMainAxisExtent: 574.0, remainingCacheExtent: 824.0, cacheOrigin: 0.0)
geometry: SliverGeometry(scrollExtent: 574.0, paintExtent: 574.0, maxPaintExtent: 574.0, cacheExtent: 574.0)
scrollExtent: 574.0
paintExtent: 574.0
maxPaintExtent: 574.0
cacheExtent: 574.0
child: RenderFlex#0b053 NEEDS-LAYOUT NEEDS-COMPOSITING-BITS-UPDATE
needs compositing
parentData: paintOffset=Offset(0.0, -0.0)
constraints: BoxConstraints(w=1034.0, h=574.0)
size: Size(1034.0, 574.0)
direction: horizontal
mainAxisAlignment: start
mainAxisSize: max
crossAxisAlignment: center
textDirection: ltr
verticalDirection: down
child 1: RenderSemanticsAnnotations#79122 relayoutBoundary=up1
needs compositing
parentData: offset=Offset(0.0, 0.0); flex=null; fit=null (can use size)
constraints: BoxConstraints(0.0<=w<=Infinity, 0.0<=h<=574.0)
size: Size(89.0, 574.0)
child: RenderPhysicalModel#2413b relayoutBoundary=up2
needs compositing
parentData: <none> (can use size)
constraints: BoxConstraints(0.0<=w<=Infinity, 0.0<=h<=574.0)
layer: PhysicalModelLayer#dd0a6
engine layer: PhysicalShapeEngineLayer#2eafd
handles: 2
elevation: 0.0
color: Color(0xffffffff)
size: Size(89.0, 574.0)
elevation: 0.0
color: Color(0xffffffff)
shadowColor: Color(0xffffffff)
shape: BoxShape.rectangle
borderRadius: BorderRadius.zero
child: _RenderInkFeatures#f1226 relayoutBoundary=up3
parentData: <none> (can use size)
constraints: BoxConstraints(0.0<=w<=Infinity, 0.0<=h<=574.0)
size: Size(89.0, 574.0)
child 2: RenderConstrainedBox#5423b relayoutBoundary=up1
parentData: offset=Offset(89.0, 0.0); flex=null; fit=null (can use size)
constraints: BoxConstraints(0.0<=w<=Infinity, 0.0<=h<=574.0)
size: Size(1.0, 574.0)
additionalConstraints: BoxConstraints(w=1.0, 0.0<=h<=Infinity)
child: RenderPositionedBox#2ef82 relayoutBoundary=up2
parentData: <none> (can use size)
constraints: BoxConstraints(w=1.0, 0.0<=h<=574.0)
size: Size(1.0, 574.0)
alignment: Alignment.center
textDirection: ltr
widthFactor: expand
heightFactor: expand
child: RenderPadding#25c65 relayoutBoundary=up3
parentData: offset=Offset(0.0, 0.0) (can use size)
constraints: BoxConstraints(0.0<=w<=1.0, 0.0<=h<=574.0)
size: Size(1.0, 574.0)
padding: EdgeInsets.zero
textDirection: ltr
child 3: RenderSemanticsAnnotations#7f0ab relayoutBoundary=up1 NEEDS-LAYOUT NEEDS-COMPOSITING-BITS-UPDATE
needs compositing
parentData: offset=Offset(90.0, 0.0); flex=1; fit=FlexFit.tight (can use size)
constraints: BoxConstraints(w=944.0, 0.0<=h<=574.0)
size: Size(944.0, 574.0)
child: RenderSemanticsAnnotations#466c4 relayoutBoundary=up2 NEEDS-LAYOUT NEEDS-COMPOSITING-BITS-UPDATE
needs compositing
parentData: <none> (can use size)
constraints: BoxConstraints(w=944.0, 0.0<=h<=574.0)
size: Size(944.0, 574.0)
child: RenderSemanticsAnnotations#4f301 relayoutBoundary=up3 NEEDS-LAYOUT NEEDS-COMPOSITING-BITS-UPDATE
needs compositing
parentData: <none> (can use size)
constraints: BoxConstraints(w=944.0, 0.0<=h<=574.0)
size: Size(944.0, 574.0)
════════════════════════════════════════════════════════════════════════════════
════════ Exception caught by scheduler library ═════════════════════════════════
Cannot hit test a render box that has never been laid out.
════════════════════════════════════════════════════════════════════════════════
════════ Exception caught by scheduler library ═════════════════════════════════
Assertion failed:
!_debugDuringDeviceUpdate
is not true
On state level, class String? addRole; and from Items<String>[] remove ''.
On User Add
onPressed: () {
bool isValid =
_formkey.currentState!.validate();
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text("form is $isValid")));
},
},
Full Widget
class _UserManagerState extends State<UserManager> {
final _formkey = GlobalKey<FormState>();
var addName = "";
var addEmail = "";
var addPassword = "";
String? addRole;
final nameController = TextEditingController();
final emailController = TextEditingController();
final passwordController = TextEditingController();
final roleController = TextEditingController();
#override
Widget build(BuildContext context) {
return MaterialApp(
home: DefaultTabController(
length: 2,
child: Scaffold(
appBar: AppBar(
toolbarHeight: 20,
bottom: const TabBar(
tabs: [
Tab(icon: Icon(Icons.person_add)),
Tab(icon: Icon(Icons.edit)),
],
),
),
body: TabBarView(
children: [
Center(
child: Form(
key: _formkey,
child: SingleChildScrollView(
reverse: true,
child: Container(
width: 420,
margin: const EdgeInsets.all(10.0),
padding: const EdgeInsets.all(16),
decoration: BoxDecoration(
border: Border.all(color: Colors.grey),
borderRadius: const BorderRadius.all(
Radius.circular(10),
),
),
child: Column(
children: [
//const SizedBox(
//height: 50,
//),
const Text(
"Add name",
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold,
color: Colors.indigo,
),
),
const SizedBox(
height: 10,
),
TextFormField(
minLines: 1,
autofocus: false,
keyboardType: TextInputType.text,
textInputAction: TextInputAction.next,
decoration: const InputDecoration(
labelText: "Name",
border: OutlineInputBorder(),
errorStyle: TextStyle(
color: Colors.redAccent, fontSize: 15),
),
controller: nameController,
validator: (value) {
if (value == null || value.isEmpty) {
return 'Please Enter Name';
}
return null;
}),
const SizedBox(
height: 10,
),
TextFormField(
autofocus: false,
minLines: 1,
keyboardType: TextInputType.emailAddress,
textInputAction: TextInputAction.next,
decoration: const InputDecoration(
labelText: "Email Address",
//hintText: "Email",
border: OutlineInputBorder(),
errorStyle: TextStyle(
color: Colors.redAccent, fontSize: 15),
),
controller: emailController,
validator: (value) {
if (value == null || value.isEmpty) {
return 'Please Enter Email ID';
} else if (!value.contains('#')) {
return 'Please Enter Valid Email ID';
}
return null;
}),
const SizedBox(
height: 10,
),
TextFormField(
minLines: 1,
autofocus: false,
obscureText: true,
keyboardType: TextInputType.text,
textInputAction: TextInputAction.next,
decoration: const InputDecoration(
labelText: "Password",
border: OutlineInputBorder(),
errorStyle: TextStyle(
color: Colors.redAccent, fontSize: 15),
),
controller: passwordController,
validator: (value) {
if (value == null || value.isEmpty) {
return 'Please Enter Password';
}
return null;
}),
const SizedBox(
height: 20,
),
//
DropdownButtonFormField(
decoration: const InputDecoration(
labelText: "department",
border: OutlineInputBorder(),
errorStyle: TextStyle(
color: Colors.redAccent, fontSize: 15),
),
hint: const Text("select department"),
value: addRole,
onChanged: (String? newValue) {
setState(() {
addRole = newValue!;
});
},
validator: (value) =>
value == null ? 'field required' : null,
items: <String>[
'hr',
'dtp'
].map<DropdownMenuItem<String>>((String value) {
return DropdownMenuItem<String>(
value: value,
child: Text(value),
);
}).toList(),
),
const SizedBox(
height: 20,
),
//
ElevatedButton(
style: ElevatedButton.styleFrom(
primary: Colors.red, // background
onPrimary: Colors.white, // foreground
),
onPressed: () {
bool isValid =
_formkey.currentState!.validate();
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text("form is $isValid")));
},
child: const Text('User Add'),
),
const SizedBox(
height: 20,
),
],
),
),
)),
),
Center(
child: Text("Test"),
)
],
),
),
),
);
}
}
On my end, the issue was on the items' list where some value was long (String length). I have resolved this way
DropdownButtonFormField(
...
items: items
.map(
(e) => DropdownMenuItem(
value: e,
child: e.length > 30
? Text('${e[0].toUpperCase()}${e.substring(1, 30)}...')
: Text("${e[0].toUpperCase()}${e.substring(1)}"),
)).toList(),
)
Related
I have a Dialog/Form like this (Flutter 3.0.5 - Web Chrome):
Future<void> showInformationDialog(BuildContext context) async {
double screenWidth = MediaQuery.of(context).size.width;
double screenHeight = MediaQuery.of(context).size.height;
return await showDialog(
context: context,
builder: (context) {
return StatefulBuilder(builder: (context, setState) {
return AlertDialog(
insetPadding: const EdgeInsets.all(10),
content: Row(children: [
SizedBox(
width: screenWidth * 0.6,
height: screenHeight * 0.5,
child: Form(
key: _formKey,
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
TextFormField(
controller: _titleEditingController,
validator: (value) {
return value!.isNotEmpty ? null : "Title";
},
decoration: const InputDecoration(hintText: "Title"),
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Expanded(
child:
TextField(
enabled: false,
controller: _dateController,
),
),
ElevatedButton(
onPressed: () {
_restorableDatePickerRouteFuture.present();
},
child: const Icon(Icons.calendar_month),
)
],
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Expanded(
child:
TextField(
enabled: false,
controller: _timeController,
),
),
ElevatedButton(
onPressed: () {
_displayTimeDialog();
},
child: const Icon(Icons.access_time_outlined),
)
],
),
const SizedBox(height: 30,),
TextFormField(
controller: _detailsEditingController,
keyboardType: TextInputType.multiline,
maxLines: null,
decoration: const InputDecoration(
hintText: "Enter Task Details",
border: OutlineInputBorder(
borderSide: BorderSide(width: 2)
),
),
),
],
)))]),
title: const Text('Create Task'),
actions: <Widget>[
InkWell(
child: const Text('OK'),
onTap: () {
if (_formKey.currentState!.validate()) {
Navigator.of(context).pop();
}
},
),
],
);
});
});
}
and I have added a percentage width/height to it. However the TextFormField does not fill the whole available space automatically (image below), and you can only predefine the number of lines which won't work for all cases. How can I make the TextFormField able to fill the available space?
If I add what Yeasin suggests in his solution, I get:
The hitTest() method was called on this RenderBox: RenderConstrainedBox#c7750 relayoutBoundary=up1:
needs compositing
creator: ConstrainedBox ← Align ← MediaQuery ← Padding ← AnimatedPadding ← Dialog ← AlertDialog ← StatefulBuilder ← Builder ← DefaultTextStyle ← CaptureAll ← MediaQuery ← ⋯
parentData: offset=Offset(0.0, 0.0) (can use size)
constraints: BoxConstraints(0.0<=w<=1491.0, 0.0<=h<=1311.0)
size: MISSING
additionalConstraints: BoxConstraints(280.0<=w<=Infinity, 0.0<=h<=Infinity)
Although this node is not marked as needing layout, its size is not set.
A RenderBox object must have an explicit size before it can be hit-tested. Make sure that the RenderBox in question sets its size during layout.
at Object.throw [as throw] (http://localhost:38447/dart_sdk.js:5080:11)
Use Expanded with maxLines:null and expands: true,
Expanded(
child: TextFormField(
keyboardType: TextInputType.multiline,
expands: true,
maxLines: null,
minLines: null,
decoration: const InputDecoration(
hintText: "Enter Task Details",
border: OutlineInputBorder(
borderSide: BorderSide(width: 2),
),
),
)),
Full dialog
Future<void> showInformationDialog(BuildContext context) async {
double screenWidth = MediaQuery.of(context).size.width;
double screenHeight = MediaQuery.of(context).size.height;
return await showDialog(
context: context,
builder: (context) {
return StatefulBuilder(builder: (context, setState) {
return AlertDialog(
insetPadding: const EdgeInsets.all(10),
content: Row(children: [
SizedBox(
// color: Colors.cyanAccent.withOpacity(.3),
width: screenWidth * 0.6,
height: screenHeight * 0.5,
child: Form(
child: Column(
mainAxisSize: MainAxisSize.max,
children: [
TextFormField(
validator: (value) {
return value!.isNotEmpty ? null : "Title";
},
decoration: const InputDecoration(hintText: "Title"),
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Expanded(
child: TextField(
enabled: false,
),
),
ElevatedButton(
onPressed: () {},
child: const Icon(Icons.calendar_month),
)
],
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Expanded(
child: TextField(
enabled: false,
),
),
ElevatedButton(
onPressed: () {},
child: const Icon(Icons.access_time_outlined),
)
],
),
const SizedBox(
height: 30,
),
Expanded(
child: TextFormField(
keyboardType: TextInputType.multiline,
expands: true,
maxLines: null,
minLines: null,
decoration: const InputDecoration(
hintText: "Enter Task Details",
border: OutlineInputBorder(
borderSide: BorderSide(width: 2),
),
),
)),
],
),
),
)
]),
title: const Text('Create Task'),
actions: <Widget>[
InkWell(
child: const Text('OK'),
onTap: () {},
),
],
);
});
});
}
I'm new to flutter. I'm creating a login page. but now getting the below error in my code when I add remember me and forget password buttons into a Row Widget to display in one row. how to solve this. for your reference I have attached the full code and UI. login_screen full dart code , login_screen UI image
RenderBox was not laid out: _RenderListTile#c9c23
relayoutBoundary=up24 NEEDS-PAINT NEEDS-COMPOSITING-BITS-UPDATE
'package:flutter/src/rendering/box.dart': Failed assertion: line 1982
pos 12: 'hasSize'
#override
Widget build(BuildContext context) {
return SingleChildScrollView(
child: Form(
key: _formKey,
autovalidateMode: AutovalidateMode.disabled,
child: Container(
margin: const EdgeInsets.all(20.0),
child: Column(
children: [
SizedBox(
height: 40,
),
TextFormField(
controller: emailEditingController,
enabled: true,
decoration: InputDecoration(
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(30.0),
),
hintText: "Email/ Username",
hintStyle: TextStyle(
color: textGrey, fontFamily: "Dubai", fontSize: 14),
),
validator: (String? UserName) {
if (UserName != null && UserName.isEmpty) {
return "Email can't be empty";
}
return null;
},
onChanged: (String? text) {
email = text!;
// print(email);
},
onSaved: (value) {
loginUserData['email'] = value!;
},
),
SizedBox(
height: 20,
),
TextFormField(
controller: passwordEditingController,
obscureText: _isObscure,
enabled: typing,
decoration: InputDecoration(
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(30.0),
),
suffixIcon: IconButton(
icon: Icon(_isObscure
? Icons.visibility
: Icons.visibility_off),
onPressed: () {
setState(() {
_isObscure = !_isObscure;
});
}),
hintText: "Password",
hintStyle: TextStyle(
color: textGrey, fontFamily: "Dubai", fontSize: 14)),
validator: (String? Password) {
if (Password != null && Password.isEmpty) {
return "Password can't be empty";
}
return null;
},
onChanged: (String? text) {
password = text!;
// print(password);
},
onSaved: (value) {
loginUserData['password'] = value!;
},
),
// this is where I got an error.
Row(
// mainAxisAlignment: MainAxisAlignment.start,
children: [
CheckboxListTile(
title: const Text(
"Remember Me",
style: TextStyle(
color: textGrey, fontFamily: "Dubai", fontSize: 14),
),
value: checkedValue,
onChanged: (newValue) {
FocusManager.instance.primaryFocus?.unfocus();
setState(() {
if (isLoading != true) {
checkedValue = newValue!;
print(newValue);
}
});
},
contentPadding: EdgeInsets.only(left: 0, top: 0),
controlAffinity:
ListTileControlAffinity.leading, // <-- leading Checkbox
),
SizedBox(
width: 5,
),
TextButton(
child: Text(
"Forget Password",
style: TextStyle(
color: textGrey, fontFamily: "Dubai", fontSize: 14),
),
onPressed: () {
//Get.to(ForgetPassword());
},
)
],
),
SizedBox(
height: 30,
),
isLoading
? SpinKitDualRing(
color: mainGreen,
size: 40,
)
: GestureDetector(
child: MainButton("Login"),
onTap: () {
},
),
SizedBox(
height: 30,
),
GestureDetector(
child: MainButton("Signup"),
onTap: () {
},
),
],
),
),
),
);
}
The issue is coming from CheckboxListTile while it is inside the Row,
Wrap CheckboxListTile with Expanded widget, it will get available width inside row.
Row(
children: [
Expanded(
child: CheckboxListTile(
More about Expanded.
I am designing a phone number input box. The default style will be like the first image, but when the textError appears, the style will break like the second image. Is there a way to keep the spacing from user text input to the bottom line like the default style when error not showing?
first image
second image
NumberTextField widget, the widget as large as shown in the picture, including the flag and the TextFieldWidget. widget
Widgets:
import 'package:flutter/material.dart';
import 'package:online_croceries/widgets/textfield_widget.dart';
class NumberTextField extends StatelessWidget {
String? urlImageFlag;
int? code;
final TextEditingController? textEditingController;
ValueChanged? onChanged;
final String? error_text;
NumberTextField({Key? key, urlImage, code, required this.textEditingController,this.onChanged, required this.error_text})
: super(key: key);
#override
Widget build(BuildContext context) {
final height = MediaQuery.of(context).size.height;
final width = MediaQuery.of(context).size.width;
return Column(
mainAxisSize: MainAxisSize.min,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
ClipRRect(
clipBehavior: Clip.antiAlias,
borderRadius: BorderRadius.circular(5.0),
child: Image.asset(
urlImageFlag ?? 'assets/images/flag_country.png',
height: (height / 100) * 3,
width: (width / 100) * 9,
fit: BoxFit.fill,
),
),
Padding(
padding: const EdgeInsets.only(left: 10.0,right:10),
child: Text(
'+${code ?? 880}',
style: const TextStyle(
fontWeight: FontWeight.w600, fontSize: 16.0),
),
),
Expanded(
child:
TextFieldWidget(
inputType: TextInputType.phone,
textController: textEditingController!,
inputAction: TextInputAction.next,
autoFocus: false,
onChanged: onChanged,
errorText: error_text,
),
),
],
),
// const Divider(thickness: 1.5, height: 0.3, color: Colors.grey),
],
);
}
}
TextFieldWidget
#override
Widget build(BuildContext context) {
return Padding(
padding: padding,
child: TextFormField(
controller: textController,
focusNode: focusNode,
onFieldSubmitted: onFieldSubmitted,
onChanged: onChanged,
autofocus: autoFocus,
textInputAction: inputAction,
obscureText: this.isObscure,
maxLength: 25,
keyboardType: this.inputType,
decoration: InputDecoration(
hintText: this.hint,
errorText: errorText,
counterText: '',
// icon: this.isIcon ? Icon(this.icon, color: iconColor) : null
),
),
);
}
Just add a errorBorder in decoration, how you want to be when error is show:
decoration: InputDecoration(
hintText: this.hint,
errorText: errorText,
counterText: '',
// icon: this.isIcon ? Icon(this.icon, color: iconColor) : null
errorBorder: //code how you want..
),
I am trying to fit in a search bar build function instead of title.
It works perfectly fine as part of the appBar body.
Here is the implementation of buildSearchBar which I want to fit inside the AppBar:
buildSearchBar(BuildContext context) {
return SliverPadding(
padding: EdgeInsets.only(left: 16.0, right: 16.0, top: 16.0),
sliver: SliverList(
delegate: SliverChildListDelegate([
Card(
color: Colors.transparent,
elevation: 8,
child: ClipRRect(
borderRadius: BorderRadius.all(Radius.circular(16.0)),
child: Container(
padding: EdgeInsets.symmetric(horizontal: 16.0),
color: Theme.of(context).accentColor,
child: TextField(
decoration: InputDecoration(
icon: Icon(Icons.search),
border: InputBorder.none,
hintStyle:
TextStyle(fontSize: 18, color: Colors.black54),
hintText: 'Search news'),
textInputAction: TextInputAction.search,
cursorColor: Colors.black54,
style: TextStyle(fontSize: 18, color: Colors.black54),
controller: TextEditingController(),
onSubmitted: (text) => searchLogic(context, text),
),
)))
]),
),
);
}
This is how I approached creating AppBar
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: buildSearchBar(context),
backgroundColor: Theme.of(context).brightness == Brightness.dark
? Colors.grey[850]
: Theme.of(context).accentColor,
),
body: CustomScrollView(
controller: scrollControllerSearchPage,
slivers: <Widget>[
SliverToBoxAdapter(
),
buildSearchBar(context),
],
),
);
}
I tried to create a column and fit it inside SizedBox but got these exceptions:
flutter: Another exception was thrown: A _RenderAppBarTitleBox expected a child of type RenderBox but received a child of type RenderSliverPadding.
flutter: Another exception was thrown: NoSuchMethodError: The method 'layout' was called on null.
flutter: Another exception was thrown: RenderBox was not laid out: _RenderAppBarTitleBox#9675d relayoutBoundary=up16 NEEDS-PAINT
flutter: Another exception was thrown: RenderBox was not laid out: RenderSemanticsAnnotations#51f2d relayoutBoundary=up15 NEEDS-PAINT NEEDS-COMPOSITING-BITS-UPDATE
flutter: Another exception was thrown: Updated layout information required for RenderErrorBox#742c7 NEEDS-LAYOUT NEEDS-PAINT to calculate semantics.
I'm trying to make a login screen in Flutter. This login connect to e-mail and password, but have some problems. The errors revolves around the object was given an infinite size during layout. Attached is the code for my Dart class and the logged errors when running the code.
What are you guys getting out of the error code I cannot resolve?
Dart class
import 'package:flutter/material.dart';
import 'package:loja_virtual/models/user_model.dart';
import 'package:scoped_model/scoped_model.dart';
class FormContainer extends StatelessWidget {
final _emailController = TextEditingController();
final _passController = TextEditingController();
final _formKey = GlobalKey<FormState>();
final _scaffoldKey = GlobalKey<ScaffoldState>();
#override
Widget build(BuildContext context) {
return Scaffold(
key: _scaffoldKey,
body: ScopedModelDescendant<UserModel>(
builder: (context, child, model) {
if (model.isLoading)
return Center(child: CircularProgressIndicator(),);
return Container(
margin: EdgeInsets.symmetric(horizontal: 20),
child: Form(
key: _formKey,
child: Column(
children: <Widget>[
TextFormField(
style: TextStyle(
color: Colors.white),
controller: _passController,
decoration: InputDecoration(
hintStyle: TextStyle(color: Colors.white,fontFamily: "WorkSansLight", fontSize: 18.0),
filled: true,
fillColor: Colors.white24,
hintText: "E-mail",
border: OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(90.0)),
borderSide: BorderSide(color: Colors.white24, width: 0.5)),
prefixIcon: const Icon(
Icons.email,
color: Colors.white,
),
),
keyboardType: TextInputType.emailAddress,
validator: (text){
if(text.isEmpty || !text.contains("#")) return "E-mail inválido!";
},
),
SizedBox(height: 16.0,),
TextFormField(
style: TextStyle(
color: Colors.white),
controller: _passController,
decoration: InputDecoration(
hintStyle: TextStyle(color: Colors.white,fontFamily: "WorkSansLight", fontSize: 18.0),
filled: true,
fillColor: Colors.white24,
hintText: "Senha",
border: OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(90.0)),
borderSide: BorderSide(color: Colors.white24, width: 0.5)),
prefixIcon: const Icon(
Icons.lock_outline,
color: Colors.white,
),
),
obscureText: true,
validator: (text){
if(text.isEmpty || text.length < 6) return "Senha inválida!";
},
),
Align(
alignment: Alignment.centerRight,
child: FlatButton(
onPressed: (){
if(_emailController.text.isEmpty)
_scaffoldKey.currentState.showSnackBar(
SnackBar(content: Text("Insira seu e-mail para recuperação!"),
backgroundColor: Colors.redAccent,
duration: Duration(seconds: 2),
)
);
else {
model.recoverPass(_emailController.text);
_scaffoldKey.currentState.showSnackBar(
SnackBar(content: Text("Confira seu e-mail!"),
backgroundColor: Colors.purple,
duration: Duration(seconds: 2),
)
);
}
},
child: Text("Esqueci minha senha",
textAlign: TextAlign.right,
style: TextStyle(color: Colors.white, fontSize: 15.0),
),
padding: EdgeInsets.zero,
),
),
SizedBox(
height: 16,
),
SizedBox(
height: 80,
width: 80,
child: new FloatingActionButton(
backgroundColor: Colors.white30,
child: Text(
"Entrar",
style: TextStyle(
fontSize: 18.0,
),
),
onPressed: () {
if (_formKey.currentState.validate()) {
}
model.signIn(
email: _emailController.text,
pass: _passController.text,
onSuccess: _onSuccess,
onFail: _onFail
);
},
),
),
],
),
),
);
},
)
);
}
void _onSuccess() {
// Navigator.of(context).pop(); Esta dando erro
}
void _onFail() {
_scaffoldKey.currentState.showSnackBar(
SnackBar(content: Text("Falha ao Entrar!"),
backgroundColor: Colors.redAccent,
duration: Duration(seconds: 3),
)
);
}
}
Errors
I/flutter ( 4207): The following assertion was thrown during performLayout():
I/flutter ( 4207): RenderCustomMultiChildLayoutBox object was given an infinite size during layout.
I/flutter ( 4207): This probably means that it is a render object that tries to be as big as possible, but it was put inside
another render object that allows its children to pick their own size.
I/flutter ( 4207): The nearest ancestor providing an unbounded height constraint is: RenderIndexedSemantics#dc596
relayoutBoundary=up3 NEEDS-LAYOUT NEEDS-PAINT
I/flutter ( 4207): creator: IndexedSemantics ← NotificationListener<KeepAliveNotification> ← KeepAlive ←
I/flutter ( 4207): AutomaticKeepAlive ← SliverList ← SliverPadding ← Viewport ← IgnorePointer-[GlobalKey#aaf31] ←
I/flutter ( 4207): Semantics ← Listener ← _GestureSemantics ←
I/flutter ( 4207): RawGestureDetector-[LabeledGlobalKey<RawGestureDetectorState>#1430c] ←
I/flutter ( 4207): parentData: index=0; layoutOffset=0.0 (can use size)
I/flutter ( 4207): constraints: BoxConstraints(w=360.0, 0.0<=h<=Infinity)
I/flutter ( 4207): semantic boundary
I/flutter ( 4207): size: Size(360.0, Infinity)
I/flutter ( 4207): index: 0
I/flutter ( 4207): The constraints that applied to the RenderCustomMultiChildLayoutBox were:
I/flutter ( 4207): BoxConstraints(0.0<=w<=360.0, 0.0<=h<=Infinity)
I/flutter ( 4207): The exact size it was given was:
I/flutter ( 4207): Size(360.0, Infinity)
My Answer:
import 'package:flutter/material.dart';
import 'package:flutter/scheduler.dart' show timeDilation;
import 'package:loja_virtual/models/user_model.dart';
import 'package:loja_virtual/widgets/sign_up_button.dart';
import 'package:flare_flutter/flare_actor.dart';
import 'package:scoped_model/scoped_model.dart';
class NewLoginScreen extends StatefulWidget {
#override
_NewLoginScreenState createState() => _NewLoginScreenState();
}
class _NewLoginScreenState extends State<NewLoginScreen> {
final _emailController = TextEditingController();
final _passController = TextEditingController();
final _formKey = GlobalKey<FormState>();
final _scaffoldKey = GlobalKey<ScaffoldState>();
#override
Widget build(BuildContext context) {
return Scaffold(
key: _scaffoldKey,
appBar: AppBar(backgroundColor: Colors.transparent),
body: ScopedModelDescendant<UserModel>(
builder: (context, child, model) {
if (model.isLoading)
return Center(
child: CircularProgressIndicator(),
);
return Form(
key: _formKey,
child: Container(
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage("images/background1.jpg"),
fit: BoxFit.cover)),
child: ListView(
padding: EdgeInsets.zero,
children: <Widget>[
Stack(
alignment: Alignment.bottomCenter,
children: <Widget>[
Column(
children: <Widget>[
Padding(
padding: EdgeInsets.only(top: 10, bottom: 10),
child: Image.asset(
"images/user1.png",
width: 130,
height: 130,
fit: BoxFit.contain,
),
),
TextFormField(
style: TextStyle(color: Colors.white),
controller: _emailController,
decoration: InputDecoration(
hintStyle: TextStyle(
color: Colors.white,
fontFamily: "WorkSansLight",
fontSize: 15.0),
filled: true,
fillColor: Colors.white24,
hintText: "E-mail",
border: OutlineInputBorder(
borderRadius:
BorderRadius.all(Radius.circular(90.0)),
borderSide: BorderSide(
color: Colors.white24, width: 0.5)),
prefixIcon: const Icon(
Icons.email,
color: Colors.white,
),
),
keyboardType: TextInputType.emailAddress,
validator: (text) {
if (text.isEmpty || !text.contains("#"))
return "E-mail inválido!";
},
),
SizedBox(
height: 10.0,
),
TextFormField(
style: TextStyle(color: Colors.white),
controller: _passController,
decoration: InputDecoration(
hintStyle: TextStyle(
color: Colors.white,
fontFamily: "WorkSansLight",
fontSize: 15.0),
filled: true,
fillColor: Colors.white24,
hintText: "Senha",
border: OutlineInputBorder(
borderRadius:
BorderRadius.all(Radius.circular(90.0)),
borderSide: BorderSide(
color: Colors.white24, width: 0.5)),
prefixIcon: const Icon(
Icons.lock_outline,
color: Colors.white,
),
),
obscureText: true,
validator: (text) {
if (text.isEmpty || text.length < 6)
return "Senha inválida!";
},
),
Align(
alignment: Alignment.centerRight,
child: FlatButton(
onPressed: () {
if (_emailController.text.isEmpty)
_scaffoldKey.currentState
.showSnackBar(SnackBar(
content: Text(
"Insira seu e-mail para recuperação!"),
backgroundColor: Colors.redAccent,
duration: Duration(seconds: 2),
));
else {
model.recoverPass(_emailController.text);
_scaffoldKey.currentState
.showSnackBar(SnackBar(
content: Text("Confira seu e-mail!"),
backgroundColor: Colors.purple,
duration: Duration(seconds: 3),
));
}
},
child: Text(
"Esqueci minha senha",
textAlign: TextAlign.right,
style: TextStyle(
color: Colors.white, fontSize: 13.0),
),
padding: EdgeInsets.zero,
),
),
SizedBox(
height: 10,
),
SizedBox(
height: 80,
width: 80,
child: new FloatingActionButton(
backgroundColor: Colors.white30,
child: Text(
"Entrar",
style: TextStyle(
fontSize: 18.0,
),
),
onPressed: () {
if (_formKey.currentState.validate()) {}
model.signIn(
email: _emailController.text,
pass: _passController.text,
onSuccess: _onSuccess,
onFail: _onFail);
},
),
),
SignUpButton()
],
),
],
),
],
),
),
);
},
),
);
}
void _onSuccess() {
Navigator.of(context).pop();
}
void _onFail() {
_scaffoldKey.currentState.showSnackBar(SnackBar(
content: Text("Falha ao Entrar!"),
backgroundColor: Colors.redAccent,
duration: Duration(seconds: 3),
));
}
}
Now it's Ok. thx
Login
Try wrapping your ScopedModelDescendant in a Flexible (or a container with fixed size). By itself, it doesn't have any concept of what size it needs to be, so you need it to be a child of something that does have size constraints.