单击 DropdownButtonFormField 时抛出错误
Throwing an error while clicking on DropdownButtonFormField
我正在尝试在带有选项卡查看器的选项卡控制器中使用 DropdownButtonFormField 在 flutter web 上。它显示但不显示下拉选项点击它显示错误请在我的代码和错误下方找到。
下面是我的示例代码:
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"),
)
],
),
),
),
);
}
}
错误如下:
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).
调试控制台:
════════ 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
在州一级,class String? addRole;
并从 Items<String>[]
中删除 ''
。
在 User Add
onPressed: () {
bool isValid =
_formkey.currentState!.validate();
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text("form is $isValid")));
},
},
全组件
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"),
)
],
),
),
),
);
}
}
我正在尝试在带有选项卡查看器的选项卡控制器中使用 DropdownButtonFormField 在 flutter web 上。它显示但不显示下拉选项点击它显示错误请在我的代码和错误下方找到。
下面是我的示例代码:
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"),
)
],
),
),
),
);
}
}
错误如下:
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).
调试控制台:
════════ 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
在州一级,class String? addRole;
并从 Items<String>[]
中删除 ''
。
在 User Add
onPressed: () {
bool isValid =
_formkey.currentState!.validate();
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text("form is $isValid")));
},
},
全组件
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"),
)
],
),
),
),
);
}
}