该表达式的类型为“void”,因此无法使用其值。 尝试检查您是否使用了正确的 API;可能有一个函数或调用返回了您意想不到的 void 。还要检查类型参数和变量,它们也可能为 void。
错误正好显示在“pop”上的第 65 行中。代码如下。
class NewExpense extends StatefulWidget {
const NewExpense({Key? key, required this.onAddExpense}): super(
key: key,
);
final void Function(Expense expense) onAddExpense;
@override
State<StatefulWidget> createState() {
return _NewExpenseState();
}
}
class _NewExpenseState extends State<NewExpense> {
final _titleController = TextEditingController();
final _amountController = TextEditingController();
DateTime? _selectedDate;
Category _selectedCategory = Category.frameset;
void _presentDatePicker() async {
final now = DateTime.now();
final firstDate = DateTime(now.year - 1, now.month, now.day);
final pickedDate = await showDatePicker(
context: context,
initialDate: now,
firstDate: firstDate,
lastDate: now,
);
setState(() {
_selectedDate = pickedDate;
});
}
void _submitExpenseData() {
double? enterAmount = double.tryParse(_amountController.text);
final amountIsInvalid = enterAmount == null || enterAmount <= 0;
if (_titleController.text.trim().isEmpty ||
amountIsInvalid ||
_selectedDate == null) {
showDialog(
context: context,
builder: (ctx) => AlertDialog(
title: const Text('Invalid Input'),
content: const Text(
'Please make sure a valid title, amount, date and category was entered.'),
actions: [
TextButton(
onPressed: () {
Navigator.pop(ctx);
},
child: Text('Okay'),
)
],
),
);
return;
}
widget.onAddExpense(
Navigator.of(context).pop(Expense(
title: _titleController.text,
amount: enterAmount!,
date: _selectedDate!,
category: _selectedCategory)));
}
@override
void dispose() {
_titleController.dispose();
_amountController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.fromLTRB(16, 16, 16, 16),
child: Column(
children: [
TextField(
controller: _titleController,
maxLength: 50,
decoration: const InputDecoration(
label: Text('Title'),
),
),
Row(
children: [
Expanded(
child: TextField(
controller: _amountController,
keyboardType: TextInputType.number,
decoration: const InputDecoration(
prefixText: '₹ ',
label: Text('Amount'),
),
),
),
const SizedBox(width: 16),
Expanded(
child: Row(
mainAxisAlignment: MainAxisAlignment.end,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Text(_selectedDate == null
? 'No date selected'
: formatter.format(_selectedDate!)),
IconButton(
onPressed: _presentDatePicker,
icon: const Icon(
Icons.calendar_month,
),
),
],
),
),
],
),
const SizedBox(
height: 16,
),
Row(
children: [
DropdownButton(
value: _selectedCategory,
items: Category.values
.map(
(category) => DropdownMenuItem(
value: category,
child: Text(
// ignore: sdk_version_since
category.name.toUpperCase(),
),
),
)
.toList(),
onChanged: (value) {
if (value == null) {
return;
}
setState(() {
_selectedCategory = value as Category;
});
}),
const Spacer(),
TextButton(
onPressed: () {
Navigator.pop(context);
},
child: const Text('Cancel'),
),
ElevatedButton(
onPressed: _submitExpenseData,
child: const Text('Save Expense'),
),
],
),
],
),
);
}
}
我不知道你的项目流程是哪个。我注意到的一件事是,您在 onAddExpense 函数下使用 pop 方法,这就是问题所在。
因为你不能使用void方法作为返回。您需要在 main 方法之后调用 pop 方法,或者通过弹出页面作为您的目标返回 Expense()。
#像这样使用
widget.onAddExpense(
Expense(
title: _titleController.text,
amount: enterAmount!,
date: _selectedDate!,
category: _selectedCategory,
),
);
Navigator.of(context).pop();
#或
Navigator.of(context).pop(
Expense(
title: _titleController.text,
amount: enterAmount!,
date: _selectedDate!,
category: _selectedCategory,
),
);