【发布时间】:2022-01-06 08:28:28
【问题描述】:
我从 Firebase 获得一份清单。列表按预期加载,但是我有两个问题。
1 - 当列表中的一个项目中的按钮被禁用时,其他项目中的所有按钮也会被禁用。我不希望这种情况发生。我怎样才能通过这个?
2 - 我从 firebase RTDB 获得“positiveCount”和“negativeCount”。我想得到总数(positiveCount +negativeCount),然后计算“positiveCount”的百分比。 (示例:positiveCount = 2,negativeCount = 2,positiveCount 的百分比应为 50%)。问题是,如果只加载一个项目,它可以完美运行。如果加载了多个项目,我会收到错误消息。
例外:
Exception has occurred.
UnsupportedError (Unsupported operation: Infinity or NaN toInt)
我的代码:
import 'package:colour/colour.dart';
import 'package:firebase_database/firebase_database.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:google_fonts/google_fonts.dart';
import 'dart:async';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
// import 'package:shared_preferences/shared_preferences.dart';
class VaccineCenterList extends StatefulWidget {
const VaccineCenterList({key}) : super(key: key);
static const String idScreen = "VaccineCenterList";
@override
_VaccineCenterListState createState() => _VaccineCenterListState();
}
class _VaccineCenterListState extends State<VaccineCenterList> {
final databaseReference = FirebaseDatabase.instance.reference();
final firestoreInstance = FirebaseFirestore.instance;
FirebaseAuth auth = FirebaseAuth.instance;
List<Hospitals> driverList = [];
late String isTrueOrFalse = "False";
// // double percentageInt = 0.0;
int totalVotes = 0;
// int percentage = 0;
int positiveCount = 0;
int negativeCount = 0;
bool buttonPressed = true;
TextEditingController hospitalCountyEditingController =
TextEditingController();
Future<List<Hospitals>> getHospitalDetails() async {
try {
if ((hospitalCountyEditingController.text != "") &&
(hospitalCountyEditingController.text != " ")) {
databaseReference
.child("Hospitals")
.child(hospitalCountyEditingController.text)
.onValue
.listen(
(event) {
setState(
() {
var value = event.snapshot.value;
driverList = Map.from(value)
.values
.map((e) => Hospitals.fromJson(Map.from(e)))
.toList();
},
);
},
);
} else {}
} catch (e) {
}
return driverList;
}
calculatePositivePercentage(
positiveCount, negativeCount) {
// this method gets the number of "yes" and "no" votes. Then calculates the
// percentage of people who voted "yes".
// total = positiveCount + negativeCount;
// percentage = (positiveCount * 100) ~/ total;
totalVotes = positiveCount + negativeCount;
int percentage = positiveCount * 100;
double votePercentage = percentage / totalVotes;
return votePercentage;
}
@override
void initState() {
super.initState();
print("I'm in the vaccine list search screen");
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.grey[100],
appBar: AppBar(
backgroundColor: Colors.grey[100],
centerTitle: true,
elevation: 0,
iconTheme: const IconThemeData(
color: Colors.black,
),
title: Text(
"Pamoja",
style: GoogleFonts.lexendMega(
fontWeight: FontWeight.bold,
color: Colors.black,
fontSize: 35,
),
),
),
body: GestureDetector(
onTap: () {
FocusScope.of(context).requestFocus(FocusNode());
},
child: SingleChildScrollView(
child: Column(
children: [
Container(
padding: const EdgeInsets.all(8.0),
child: TextField(
controller: hospitalCountyEditingController,
keyboardType: TextInputType.text,
textCapitalization: TextCapitalization.words,
decoration: InputDecoration(
border: const OutlineInputBorder(
borderSide: BorderSide(
color: Colors.black,
style: BorderStyle.solid,
width: 1,
),
),
labelText: "Search County",
labelStyle: const TextStyle(
fontSize: 14.0,
color: Colors.blueGrey,
),
hintStyle: GoogleFonts.lexendMega(
color: Colors.grey,
fontSize: 10,
),
),
style: GoogleFonts.lexendMega(
fontSize: 14,
color: Colors.black,
),
),
),
ElevatedButton(
onPressed: () {
buttonPressed = false;
setState(() {
FocusScope.of(context).requestFocus(
FocusNode(),
);
driverList.clear();
if (hospitalCountyEditingController.text == "" ||
hospitalCountyEditingController.text == " ") {
isTrueOrFalse = "False";
} else {
isTrueOrFalse = "True";
}
});
getHospitalDetails();
},
child: Text(
"Search",
style: GoogleFonts.lexendMega(
fontWeight: FontWeight.bold,
),
),
),
SizedBox(
height: MediaQuery.of(context).size.height,
// color: Colors.black,
child: Padding(
padding: const EdgeInsets.all(12.0),
child: driverList.isEmpty
? Center(
// child: CircularProgressIndicator(),
child: (isTrueOrFalse == "True")
? const CircularProgressIndicator()
: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Padding(
padding: const EdgeInsets.all(8.0),
child: Text(
"Search for one of the counties below",
style: GoogleFonts.lexendMega()),
),
Text(
"Nairobi, Baringo, Busia, Bomet, Bungoma, Elgeyo Marakwet, Embu, Garissa, Homa Bay, Isiolo, Kajiado, Kakamega, Kericho, Kiambu, Kilifi, Kirinyaga, Kisii, Kisumu, Kitui, Kwale, Laikipia, Lamu, Machakos, Makueni, Mandera, Marsabit, Meru, Migori, Mombasa, Muranga, Nakuru, Nandi, Narok, Nyamira, Nyandarua, Nyeri, Samburu, Siaya County, Taita Taveta, Tana River County, Tharaka Nithi, Trans Nzoia, Turkana, Uasin Gishu, Vihiga, Wajir, West Pokot",
textAlign: TextAlign.center,
style: GoogleFonts.lexendMega(
fontWeight: FontWeight.bold,
),
),
],
),
)
: ListView.builder(
itemCount: driverList.length,
itemBuilder: (context, int index) {
final Hospitals hospitals = driverList[index];
final String hospitalLocaiton = hospitals.location;
final String hospitalPhone = hospitals.phone;
// final int totalVotes = hospitals.totalVotes;
final String hospitalName = hospitals.name;
// final String county = hospitals.county;
positiveCount = hospitals.positiveCount;
negativeCount = hospitals.negativeCount;
// final int percentage = positiveCount * 100;
// final double percentageInt =
// percentage / totalVotes;
// ignore: unused_local_variable
final double setpercentage =
calculatePositivePercentage(positiveCount, negativeCount);
**final percentageInt = setpercentage.toInt();**
return Padding(
padding: const EdgeInsets.all(8.0),
child: Card(
elevation: 0,
child: ExpansionTile(
title: Text(
hospitalName.toUpperCase(),
style: GoogleFonts.lexendMega(),
textAlign: TextAlign.center,
),
children: [
Column(
children: [
Container(
child: (hospitalPhone.isNotEmpty)
? ElevatedButton(
onPressed: () {
Clipboard.setData(
ClipboardData(
text: hospitalPhone,
),
);
ScaffoldMessenger.of(
context)
.showSnackBar(
const SnackBar(
backgroundColor:
Colors.green,
content: Text(
"Number Copied",
textAlign:
TextAlign.center,
),
),
);
},
child: Text(
hospitalPhone,
textAlign: TextAlign.center,
style:
GoogleFonts.lexendMega(
fontSize: 13),
),
style:
ElevatedButton.styleFrom(
elevation: 0,
),
)
: const Text(""),
),
const SizedBox(
height: 5,
),
hospitalLocaiton.isNotEmpty
? Container(
padding:
const EdgeInsets.all(8),
decoration: BoxDecoration(
border: Border.all(
color: Colors.black,
),
borderRadius:
BorderRadius.circular(10),
),
child: Text(
hospitalLocaiton,
textAlign: TextAlign.center,
style: GoogleFonts.lexendMega(
fontSize: 12,
),
),
)
: Text(
hospitalLocaiton,
textAlign: TextAlign.center,
style: GoogleFonts.lexendMega(
fontSize: 12,
),
),
const SizedBox(
height: 10,
),
Text(
"$percentageInt% (percent) of voters say this hospital administer vaccines.",
textAlign: TextAlign.center,
style: GoogleFonts.lexendMega(
fontWeight: FontWeight.bold,
fontSize: 12,
color: Colors.deepPurple[400],
),
),
const SizedBox(
height: 10,
),
const Divider(
// thickness: 1,
indent: 20,
endIndent: 20,
color: Colors.black87,
),
const SizedBox(
height: 10,
),
Text(
"Does this Hospital administer Vaccines?\n(To help the public, please vote only if you know.)",
textAlign: TextAlign.center,
style: GoogleFonts.lexendMega(
fontSize: 12,
fontWeight: FontWeight.bold,
),
),
// Container(
// child: (positiveCount == 0)
// ? Text("Votes: $positiveCount")
// : Text("Votes: " +
// positiveCount.toString()),
// ),
Column(
children: [
Row(
mainAxisAlignment:
MainAxisAlignment.spaceEvenly,
children: [
ElevatedButton(
onLongPress: buttonPressed
? () {
buttonPressed = false;
ScaffoldMessenger.of(
context)
.showSnackBar(
const SnackBar(
backgroundColor:
Colors
.purpleAccent,
content: Text(
"Vote Removed",
textAlign:
TextAlign
.center,
),
),
);
undoPositiveIncrement(
hospitalName);
}
: null,
onPressed: buttonPressed ? () {
ScaffoldMessenger.of(
context)
.showSnackBar(
const SnackBar(
backgroundColor:
Colors.greenAccent,
content: Text(
"Voted Yes",
textAlign:
TextAlign.center,
),
),
);
positiveIncrement(
hospitalName);
} : null,
child: Text(
"Yes - $positiveCount",
style: GoogleFonts
.lexendMega(),
),
style:
ElevatedButton.styleFrom(
primary: Colour("#87D68D"),
),
),
ElevatedButton(
onLongPress: buttonPressed ? () {
ScaffoldMessenger.of(
context)
.showSnackBar(
const SnackBar(
backgroundColor:
Colors.purpleAccent,
content: Text(
"Vote Removed",
textAlign:
TextAlign.center,
),
),
);
undoNegativeIncrement(
hospitalName);
} : null,
onPressed: buttonPressed ? () {
ScaffoldMessenger.of(
context)
.showSnackBar(
const SnackBar(
backgroundColor:
Colors.redAccent,
content: Text(
"Voted",
textAlign:
TextAlign.center,
),
),
);
negativeIncrement(
hospitalName);
} : null,
child: Text(
"No - $negativeCount",
style: GoogleFonts
.lexendMega(),
),
style:
ElevatedButton.styleFrom(
primary: Colour("#E3655B"),
),
),
],
),
const SizedBox(
height: 10,
),
Text(
"Total No. of Votes: ",
style: GoogleFonts.lexendMega(
fontSize: 12),
),
const SizedBox(
height: 10,
),
Text(
"1 - To vote, tap once\n2 - To Undo vote, tap and hold",
style: GoogleFonts.lexendMega(
fontSize: 12,
),
textAlign: TextAlign.start,
),
const SizedBox(
height: 10,
),
],
),
],
),
],
),
),
);
},
),
),
),
],
),
),
),
);
}
}
class Hospitals {
final String name;
final String phone;
final String location;
// final String county;
final int positiveCount;
final int negativeCount;
// final int intPercentage;
// final int totalVotes;
Hospitals({
required this.name,
required this.phone,
required this.location,
// required this.county,
required this.positiveCount,
required this.negativeCount,
// required this.intPercentage,
// required this.totalVotes,
});
static Hospitals fromJson(Map<String, dynamic> json) {
return Hospitals(
name: json['HospitalName'],
phone: json['HospitalPhone'],
// county: json['county'],
location: json['HospitalAddres'],
positiveCount: json['poitiveCount'],
negativeCount: json['negativeCount'],
// intPercentage: json['intPercentage'],
// totalVotes: json['totalVotes']
);
}
}
问题 2 的解决方案:
calculatePositivePercentage(positiveCount, negativeCount) {
// this method gets the number of "yes" and "no" votes. Then calculates the
// percentage of people who voted "yes".
double votePercentage = 0;
if (positiveCount == 0 && negativeCount == 0) {
try {
return votePercentage.toInt();
} catch (e) {
print(e);
}
} else {
try {
totalVotes = positiveCount + negativeCount;
int percentage = positiveCount * 100;
votePercentage = percentage / totalVotes;
return votePercentage.toInt();
} catch (e) {
print(e);
}
}
}
【问题讨论】:
-
您能突出显示导致错误的行吗?谢谢
-
@HelsDying 抱歉,我找不到突出显示它的位置。 " 最终百分比Int = setpercentage.toInt(); "
-
问题 2,已解决。