如果你们能帮我的话我会很感激的,这让我晚上睡不着。
为什么属性的键位于key:Key(people[index].id.toString())是否返回空列表?因此,代码只是抛出一个异常,并且无法运行,因为值为0:“无效值:有效值范围为空:0”。
有什么线索告诉我该怎么解决吗?
Person.dart:
import 'package:flutter/material.dart';
class Person {
int id = UniqueKey().hashCode;
late String personName;
late double personWeight;
late double personHeight;
late double personBMI;
bool personHasGoodBMI = false;
String get name => personName;
set name(String name) => personName = name;
double get weight => personWeight;
set weight(double weight) => personWeight = weight;
double get height => personHeight;
set height(double height) => personHeight = height;
double get bmi => personBMI;
set bmi(double bmi) => personBMI = bmi;
bool get isValidPerson => personName.isNotEmpty && personWeight > 0 && personHeight > 0;
set isValidPerson(bool isValidPerson) => isValidPerson = isValidPerson;
bool get hasGoodBMI => personHasGoodBMI;
set hasGoodBMI(bool hasGoodBMI) => personHasGoodBMI = hasGoodBMI;
Person({this.personName = '', this.personWeight = 0, this.personHeight = 0, this.personBMI = 0});
}
person_CRUD.dart:
import 'package:d1_calculadoraimc/models/person.dart';
class PersonCRUD {
final List<Person> _persons = [];
Future<void> addPerson(Person person) async {
await Future.delayed(const Duration(microseconds: 200));
_persons.add(person);
}
Future<void> removePerson(Person person) async {
await Future.delayed(const Duration(microseconds: 200));
_persons.remove(person);
}
Future<void> updatePerson(String id, bool isGood) async {
await Future.delayed(const Duration(microseconds: 200));
final person = _persons.firstWhere((element) => element.id == id);
person.hasGoodBMI = isGood;
}
Future<List<Person>> listPersons() async {
await Future.delayed(const Duration(microseconds: 200));
return _persons;
}
}
calculate_IMC.dart:
class IMCCalculator {
Person person = Person();
static double calculate(Person person) {
double heightInMeters = person.height / 100.0;
return person.weight / (heightInMeters * heightInMeters);
}
Person returnIMCPerson(double height, double weight) {
person.height = height;
person.weight = weight;
person.bmi = calculate(person);
person.bmi = double.parse(person.bmi.toStringAsFixed(2));
return person;
}
}
主文件:
import 'package:d1_calculadoraimc/person_CRUD.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'calculate_IMC.dart';
void main() {
runApp(MaterialApp(
title: 'Calculadora IMC',
theme: ThemeData(
primarySwatch: Colors.blue,
textTheme: const TextTheme(
titleLarge: TextStyle(
fontSize: 24.0,
fontWeight: FontWeight.bold,
),
),
),
home: const _CalculateIMC(),
));
}
class _CalculateIMC extends StatefulWidget {
const _CalculateIMC({Key? key}) : super(key: key);
@override
_CalculateIMCState createState() => _CalculateIMCState();
}
class _CalculateIMCState extends State<_CalculateIMC> {
final _formKey = GlobalKey<FormState>();
final TextEditingController _nameController = TextEditingController();
final TextEditingController _heightController = TextEditingController();
final TextEditingController _weightController = TextEditingController();
var crud = PersonCRUD();
var people = <Person>[];
IMCCalculator imcCalculator = IMCCalculator();
Person person = Person();
void getPeople() async {
people = await crud.listPersons();
setState(() {});
}
@override
void initState() {
getPeople();
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Calculadora IMC'),
),
floatingActionButton: FloatingActionButton(
onPressed: () {
person.name = "";
person.height = 0.0;
person.weight = 0.0;
showDialog(
context: context,
builder: (BuildContext bc) => AlertDialog(
title: const Text("Enviar informações"),
content: Form(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
TextFormField(
key: _formKey,
controller: _nameController,
decoration: const InputDecoration(
labelText: 'Nome',
),
validator: (value) {
if (value == null || value.isEmpty) {
return 'Por favor, insira um nome';
}
return null;
},
),
TextFormField(
key: _formKey,
controller: _heightController,
decoration: const InputDecoration(
labelText: 'Altura (cm)',
),
keyboardType: TextInputType.number,
inputFormatters: [
FilteringTextInputFormatter.digitsOnly,
],
validator: (value) {
if (value == null || value.isEmpty) {
return 'Por favor, insira uma altura';
}
return null;
},
),
TextFormField(
key: _formKey,
controller: _weightController,
decoration: const InputDecoration(
labelText: 'Peso (kg)',
),
keyboardType: TextInputType.number,
inputFormatters: [
FilteringTextInputFormatter.digitsOnly,
],
validator: (value) {
if (value == null || value.isEmpty) {
return 'Por favor, insira um peso';
}
return null;
},
),
],
),
),
actions: [
ElevatedButton(
onPressed: () => Navigator.of(context).pop(),
child: const Icon(Icons.cancel_rounded),
),
ElevatedButton(
onPressed: () async {
if (person.isValidPerson) {
await crud.addPerson(Person(
personName: _nameController.text,
personHeight: double.parse(_heightController.text),
personWeight: double.parse(_weightController.text),
personBMI: imcCalculator
.returnIMCPerson(
double.parse(_heightController.text),
double.parse(_weightController.text))
.bmi
.toDouble()));
setState(() {
getPeople();
});
Navigator.of(context).pop();
} else {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(
content: Text("Preencha todos os campos"),
),
);
}
setState(() {
getPeople();
});
},
child: const Icon(Icons.send_rounded),
),
],
),
);
},
child: const Icon(Icons.add_rounded),
),
body: Container(
margin: const EdgeInsets.symmetric(horizontal: 20, vertical: 20),
child: Column(children: [
Expanded(child: ListView.builder(itemBuilder: (context, index) {
return Dismissible(
key: Key(people[index].id.toString()),
onDismissed: (DismissDirection direction) async {
await crud.removePerson(people[index]);
getPeople();
},
child: ListTile(
title: Text(
people[index].name,
style: const TextStyle(fontSize: 24),
),
subtitle: Text(
"IMC: ${people[index].bmi}",
style: const TextStyle(fontSize: 16),
),
trailing: Icon(
people[index].hasGoodBMI
? Icons.sentiment_satisfied_alt_rounded
: Icons.sentiment_dissatisfied_rounded,
color:
people[index].hasGoodBMI ? Colors.green : Colors.red,
),
),
);
}))
])));
}
}
1条答案
按热度按时间y1aodyip1#
你得到错误的原因是
itemBuilder
被调用时people
是空的。要解决这个问题,请将
ListView.builder
替换为一个私有方法,该方法返回一个取决于people
大小的小部件:使用前:
之后: