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
CodePudding user response:
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"),
)
],
),
),
),
);
}
}