当我尝试在flutter应用程序的警报对话框中添加带有日期和时间选择器的下拉菜单时,UI呈现问题。我已经尝试解决此问题已有一段时间了,但无济于事。这是我得到的输出:
我的代码:
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:firebase_database/firebase_database.dart';
import 'package:test_prep/utils/Reminder.dart';
import 'package:intl/intl.dart';
class RemindersPage extends StatefulWidget {
@override
_RemindersPageState createState() => _RemindersPageState();
}
class _RemindersPageState extends State<RemindersPage> {
final TextEditingController _titleController = new
TextEditingController();
List<DropdownMenuItem<Future>> dateDrop = [];
List<DropdownMenuItem<Future>> timeDrop = [];
int selected = null;
void loadDateData() {
dateDrop = [];
dateDrop.add(new DropdownMenuItem(
child: new Text('Pick Date'),
value: _selectedDate(context),
));
}
void loadTimeData() {
timeDrop = [];
timeDrop.add(new DropdownMenuItem(
child: new Text('Pick a Time'),
value: _selectedTime(context),
));
}
@override
Widget build(BuildContext context) {
// loadDateData(); // loadTimeData();
return Scaffold(
backgroundColor: Colors.black87,
body: Column(children: <Widget>[]),
// Floating Action button
floatingActionButton: new FloatingActionButton(
tooltip: "Add Item",
backgroundColor: Colors.greenAccent,
child: new ListTile(
title: Icon(
Icons.add,
),
),
onPressed: _showFormDialog),
bottomNavigationBar: new Theme(
data: Theme.of(context)
.copyWith(canvasColor: Colors.grey, primaryColor:
Colors.white),
child: new BottomNavigationBar(
items: [
new BottomNavigationBarItem(
icon: new Icon(Icons.filter_none),
title: new Text("Reminders")),
new BottomNavigationBarItem(
icon: new Icon(Icons.all_out), title: new Text("Quizes"))
],
onTap: (int i) => debugPrint("You tapped $i"),
),
),
);
}
// Alert Dialog
void _showFormDialog() {
var alert = new AlertDialog(
title: Text("Set Reminder"),
content: Column(children: <Widget>[
Expanded(
child: TextField(
controller: _titleController,
autofocus: true,
decoration: InputDecoration(
labelText: 'Name of Reminder',
hintText: "eg. Test on Thursday!",
icon: Icon(Icons.title),
),
),
),
// Date
_dropDownDate(),
// Time
_dropDownTime()
]),
actions: <Widget>[
new FlatButton(
onPressed: () => debugPrint("Save button"), child:
Text('Save')),
new FlatButton(
onPressed: () => Navigator.pop(context), child:
Text('Cancel'))
],
);
showDialog(
context: context,
builder: (_) {
return alert;
});
}
// Date and time picker
DateTime _date = new DateTime.now();
TimeOfDay _time = new TimeOfDay.now();
Future<Null> _selectedDate(BuildContext context) async {
final DateTime picked = await showDatePicker(
context: context,
initialDate: _date,
firstDate: new DateTime(2018),
lastDate: new DateTime(2019));
if (picked != null) {
debugPrint('Date selected: ${_date.toString()}');
setState(() {
_date = picked;
});
}
}
Future<Null> _selectedTime(BuildContext context) async {
final TimeOfDay picked =
await showTimePicker(context: context, initialTime: _time);
if (picked != null && picked != _time) {
debugPrint('Time selected: ${_time.toString()}');
setState(() {
_time = picked;
});
}
}
_dropDownDate() {
var drop_date = Container(
child: Row(mainAxisAlignment: MainAxisAlignment.start, children:
[
DropdownButton(
value: selected,
items: dateDrop,
hint: Text('Pick a date'),
onChanged: (value) {
selected = value;
setState(() {});
}),
]));
return drop_date;
}
_dropDownTime() {
var drop_time = Container(
child: Row(mainAxisAlignment: MainAxisAlignment.start, children:
[
DropdownButton(
value: selected,
items: timeDrop,
hint: Text('Pick a time'),
onChanged: (value) {
selected = value;
setState(() {});
}),
]));
return drop_time;
}
}
Flutter运行时消息:
Syncing files to device iPhone X...
flutter: ══╡ EXCEPTION CAUGHT BY RENDERING LIBRARY ╞═════════════════════════════════════════════════════════
flutter: The following ArgumentError was thrown during paint():
flutter: Invalid argument(s): 0.0
flutter:
flutter: When the exception was thrown, this was the stack:
flutter: #0 double.clamp (dart:core/runtime/libdouble.dart:144:7)
flutter: #1 _DropdownMenuPainter.paint (package:flutter/src/material/dropdown.dart:57:33)
flutter: #2 RenderCustomPaint._paintWithPainter (package:flutter/src/rendering/custom_paint.dart:520:13)
flutter: #3 RenderCustomPaint.paint (package:flutter/src/rendering/custom_paint.dart:558:7)
flutter: #4 RenderObject._paintWithContext (package:flutter/src/rendering/object.dart:2085:7)
flutter: #5 PaintingContext.paintChild (package:flutter/src/rendering/object.dart:171:13)
flutter: #6 _RenderProxyBox&RenderBox&RenderObjectWithChildMixin&RenderProxyBoxMixin.paint (package:flutter/src/rendering/proxy_box.dart:126:15)
flutter: #7 PaintingContext.pushLayer (package:flutter/src/rendering/object.dart:367:12)
flutter: #8 PaintingContext.pushOpacity (package:flutter/src/rendering/object.dart:491:5)
flutter: #9 RenderAnimatedOpacity.paint (package:flutter/src/rendering/proxy_box.dart:904:15)
flutter: #10 RenderObject._paintWithContext (package:flutter/src/rendering/object.dart:2085:7)
flutter: #11 PaintingContext.paintChild (package:flutter/src/rendering/object.dart:171:13)
flutter: #12 RenderShiftedBox.paint (package:flutter/src/rendering/shifted_box.dart:70:15)
flutter: #13 RenderObject._paintWithContext (package:flutter/src/rendering/object.dart:2085:7)
flutter: #14 PaintingContext.paintChild (package:flutter/src/rendering/object.dart:171:13)
flutter: #15 _RenderProxyBox&RenderBox&RenderObjectWithChildMixin&RenderProxyBoxMixin.paint (package:flutter/src/rendering/proxy_box.dart:126:15)
flutter: #16 RenderObject._paintWithContext (package:flutter/src/rendering/object.dart:2085:7)
flutter: #17 PaintingContext._repaintCompositedChild (package:flutter/src/rendering/object.dart:128:11)
flutter: #18 PaintingContext.repaintCompositedChild (package:flutter/src/rendering/object.dart:96:5)
flutter: #19 PipelineOwner.flushPaint (package:flutter/src/rendering/object.dart:852:29)
flutter: #20 _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding&PaintingBinding&SemanticsBinding&RendererBinding.drawFrame (package:flutter/src/rendering/binding.dart:272:19)
flutter: #21 _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding&PaintingBinding&SemanticsBinding&RendererBinding&WidgetsBinding.drawFrame (package:flutter/src/widgets/binding.dart:654:13)
flutter: #22 _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding&PaintingBinding&SemanticsBinding&RendererBinding._handlePersistentFrameCallback (package:flutter/src/rendering/binding.dart:208:5)
flutter: #23 _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding._invokeFrameCallback (package:flutter/src/scheduler/binding.dart:990:15)
flutter: #24 _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding.handleDrawFrame (package:flutter/src/scheduler/binding.dart:930:9)
flutter: #25 _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding._handleDrawFrame (package:flutter/src/scheduler/binding.dart:842:5)
flutter: #26 _invoke (dart:ui/hooks.dart:128:13)
flutter: #27 _drawFrame (dart:ui/hooks.dart:117:3)
flutter:
flutter: The following RenderObject was being processed when the exception was fired:
flutter: RenderCustomPaint#556fb relayoutBoundary=up2
flutter: creator: CustomPaint ← FadeTransition ← _DropdownMenu<Object> ← CustomSingleChildLayout ← Builder
flutter: ← MediaQuery ← Builder ← RepaintBoundary-[GlobalKey#4c3ae] ← IgnorePointer ← AnimatedBuilder ←
flutter: RepaintBoundary ← _FocusScopeMarker ← ⋯
flutter: parentData: <none> (can use size)
flutter: constraints: BoxConstraints(w=148.0, 0.0<=h<=716.0)
flutter: size: Size(148.0, 16.0)
flutter: This RenderObject had the following descendants (showing up to depth 5):
flutter: RenderSemanticsAnnotations#151e5 relayoutBoundary=up3 NEEDS-PAINT
flutter: RenderCustomPaint#b9211 relayoutBoundary=up4 NEEDS-PAINT
flutter: _RenderInkFeatures#13585 relayoutBoundary=up5 NEEDS-PAINT
flutter: RenderRepaintBoundary#ed5d6 relayoutBoundary=up6 NEEDS-PAINT
flutter: RenderCustomPaint#f5290 relayoutBoundary=up7 NEEDS-PAINT
flutter: ════════════════════════════════════════════════════════════════════════════════════════════════════
flutter: Another exception was thrown: Invalid argument(s): 0.0
flutter: Another exception was thrown: Invalid argument(s): 0.0
flutter: Another exception was thrown: Invalid argument(s): 0.0
flutter: Another exception was thrown: Invalid argument(s): 0.0
flutter: Another exception was thrown: Invalid argument(s): 0.0
flutter: Another exception was thrown: Invalid argument(s): 0.0
[C2.1 748F7D32-4C53-4798-B15B-8E3BDB7D9006 2601:196:4801:b518:c076:dbf1:83d3:ada3.50444<->2607:f8b0:4002:c08::8b.443]
Connected Path: satisfied (Path is satisfied), interface: en0
Duration: 121.165s, DNS @0.004s took 0.008s, TCP @0.018s took 0.055s, TLS took 0.137s
bytes in/out: 3879/764, packets in/out: 10/8, rtt: 0.056s, retransmitted packets: 0, out-of-order packets: 0
[C3.1 67E05789-ED99-4A78-A900-D136E04B908C 2601:196:4801:b518:c076:dbf1:83d3:ada3.50445<->2607:f8b0:4002:c08::8b.443]
Connected Path: satisfied (Path is satisfied), interface: en0
Duration: 120.368s, DNS @0.002s took 0.004s, TCP @0.008s took 0.056s, TLS took 0.137s
bytes in/out: 3591/1188, packets in/out: 9/9, rtt: 0.058s, retransmitted packets: 0, out-of-order packets: 0
[C1.1 89EEE9E8-79C7-4861-9FD9-148DA484E6BE 2601:196:4801:b518:c076:dbf1:83d3:ada3.50428<->2607:f8b0:4002:813::200a.443]
Connected Path: satisfied (Path is satisfied), interface: en0
Duration: 240.659s, DNS @0.002s took 0.031s, TCP @0.036s took 0.058s, TLS took 0.563s
bytes in/out: 3394/1027, packets in/out: 10/9, rtt: 0.057s, retransmitted packets: 0, out-of-order packets: 0
答案 0 :(得分:3)
您需要创建一个新的StatefulWidget
类,该类应返回您的AlertDialog
Future _showDialog(context) async {
return await showDialog<void>(
context: context,
builder: (BuildContext context) {
return AlertDialog(
content: StatefulBuilder(
builder: (BuildContext context, StateSetter setState) {
return Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
//your code dropdown button here
]),
);
},
),
);
},
);
}
您可以在此处查看flutter的文档: Flutter AlertDialog Stateful Widget
答案 1 :(得分:0)
好吧,您的代码有几个陷阱。
第一个是您正在使用DropdownMenuItem
参数化Future
。恐怕不可能。该文档说,它们必须是一致的类型。我认为您收到的错误是因为框架无法绘制与这些类型关联的值。
您还忘记了初始化下拉列表。
我给你一个可行的解决方案。我希望这是您所追求的。它使用一个自定义的下拉按钮显示Timepicker小部件,而不显示列表菜单。
import 'package:flutter/material.dart';
void main() => runApp(new MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new MaterialApp(
title: 'Flutter Demo',
theme: new ThemeData(
primarySwatch: Colors.blue,
),
home: new RemindersPage(),
);
}
}
class RemindersPage extends StatefulWidget {
@override
_RemindersPageState createState() => _RemindersPageState();
}
class _RemindersPageState extends State<RemindersPage> {
final TextEditingController _titleController = new TextEditingController();
DateTime _date = new DateTime.now();
onDateChanged(DateTime date) {
_date = date;
//setState(() {}); //optional
}
// Alert Dialog
void _showFormDialog() {
var alert = new AlertDialog(
title: Text("Set Reminder"),
content: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
TextField(
controller: _titleController,
autofocus: true,
decoration: InputDecoration(
labelText: 'Name of Reminder',
hintText: "eg. Test on Thursday!",
icon: Icon(Icons.title),
),
),
// Date
SelectDateButton(
date: _date,
dateCallback: onDateChanged,
),
],
),
actions: <Widget>[
new FlatButton(
onPressed: () => debugPrint("Save button"), child: Text('Save')),
new FlatButton(
onPressed: () => Navigator.pop(context), child: Text('Cancel'))
],
);
showDialog(
context: context,
builder: (_) {
return alert;
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.black87,
body: Column(children: <Widget>[]),
// Floating Action button
floatingActionButton: new FloatingActionButton(
tooltip: "Add Item",
backgroundColor: Colors.greenAccent,
child: new ListTile(title: Icon(Icons.add)),
onPressed: _showFormDialog,
),
);
}
}
class SelectDateButton extends StatefulWidget {
final DateTime date;
final ValueChanged<DateTime> dateCallback;
SelectDateButton({Key key, this.date, this.dateCallback}) : super(key: key);
@override
SelectDateButtonState createState() {
return new SelectDateButtonState();
}
}
class SelectDateButtonState extends State<SelectDateButton> {
DateTime _date;
@override
void initState() {
super.initState();
_date = widget.date;
}
void selectDate(BuildContext context) async {
final DateTime picked = await showDatePicker(
context: context,
initialDate: _date,
firstDate: new DateTime(2018),
lastDate: new DateTime(2019),
);
if (picked != null) {
widget.dateCallback(picked);
_date = picked;
setState(() {});
}
}
@override
Widget build(BuildContext context) {
return FlatButton(
onPressed: () => selectDate(context),
child: Row(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Text("${_date.toString().substring(0, 10)}"),
Icon(Icons.arrow_drop_down),
],
),
);
}
}