【发布时间】:2020-11-30 13:04:25
【问题描述】:
知道为什么我的货币映射在 CurrencyConverterState 类中为空吗?我正在将 API 中的货币加载到类 API 中的货币映射(请参阅类 API 的代码),并且还尝试在加载完成后设置状态。将 API 中的货币加载到我的货币地图后,我还可以从地图中访问汇率,这意味着我的地图工作正常且不为空。我通过打印货币汇率进行了测试,结果很好。但这仅适用于 API 类。问题是,一旦我在 CurrencyConverterState 类中测试我的货币地图,它就会说地图为空,并且我被困在循环进度指示器中(请参阅 CurrencyConverterState 类的代码)。我真的不知道为什么它说地图为空。任何帮助表示赞赏。
API 类代码:
class API
{
var fromTextController = new TextEditingController();
Map<dynamic, dynamic> currencies;
String fromCurrency;
String toCurrency;
String result;
API(String from, String to){
fromCurrency = from;
toCurrency = to;
}
Future<dynamic> loadCurrencies() async {
String uri = "http://api.openrates.io/latest";
var response = await http
.get(Uri.encodeFull(uri), headers: {"Accept": "application/json"});
var responseBody = json.decode(response.body);
Map curMap = responseBody['rates'];
currencies = curMap;
setState(() {});
print (currencies["SEK"]);
}
Future<dynamic> doConversion() async {
String uri =
"http://api.openrates.io/latest?base=$fromCurrency&symbols=$toCurrency";
var response = await http
.get(Uri.encodeFull(uri), headers: {"Accept": "application/json"});
var responseBody = json.decode(response.body);
setState(() {
result = (double.parse(fromTextController.text) *
(responseBody["rates"][toCurrency]))
.toString();
});
setState(() {});
return "Success";
}
void setState(Null Function() param0) {}
}
CurrencyConverterState 类代码:
class CurrencyConverterState extends State<CurrencyConverter> {
final API api = new API("USD", "SEK");
CurrencyConverterState();
int i = 1;
@override
void initState() {
super.initState();
api.loadCurrencies();
api.fromTextController.addListener(doConversion);
setState(() {
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
resizeToAvoidBottomPadding: false,
backgroundColor: Theme.of(context).primaryColor,
body: api.currencies?.keys == null
? Center(child: CircularProgressIndicator())
: Stack(children: [
Positioned(
top: 30,
child: Container(
alignment: Alignment.center,
height: MediaQuery.of(context).size.height / 2,
width: MediaQuery.of(context).size.width,
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Card(
elevation: 10,
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Text(
'Converter',
style: TextStyle(
color: Colors.black, fontSize: 22.0),
),
ListTile(
title: TextField(
controller: api.fromTextController,
decoration: InputDecoration(
hintText: 'Enter a number'),
style: TextStyle(
fontSize: 20.0, color: Colors.black),
keyboardType: TextInputType.numberWithOptions(
decimal: true),
),
trailing:
buildDropDownButton(api.fromCurrency),
),
ListTile(
title: Chip(
label: api.result != null
? Container(
width: 1000,
height: 40,
child: Text(
api.result,
style: Theme.of(context)
.textTheme
.headline4,
),
)
: Container(
width: 1000,
height: 40,
child: Text(" "))),
trailing:
buildDropDownButton(api.toCurrency),
),
],
)),
),
),
),
]));
}
Widget buildDropDownButton(String currencyCategory) {
return DropdownButton(
value: currencyCategory,
dropdownColor: Colors.white,
icon: Icon(Icons.arrow_downward),
iconSize: 24,
items: api.currencies.keys.map((dynamic value) => DropdownMenuItem(
value: value,
child: Row(children: <Widget>[
Text(value),
])))
.toList(),
onChanged: (dynamic value) {
if (currencyCategory == api.fromCurrency) {
api.fromCurrency = value;
} else {
api.toCurrency = value;
}
setState(() {});
});
}
doConversion() {
api.doConversion();
setState(() {});
}
}
【问题讨论】: