Flutter - 多次调用 API 并使用从互联网返回的更改更新 UI
Posted
技术标签:
【中文标题】Flutter - 多次调用 API 并使用从互联网返回的更改更新 UI【英文标题】:Flutter - Making several calls to an API and updating the UI with the changes gotten back from internet 【发布时间】:2021-04-04 09:54:23 【问题描述】:`
import 'package:http/http.dart' as http;
import 'dart:convert';
class BinDetails
BinDetails(this.url);
String url;
Future getCardMetadata() async
try
http.Response response = await http.get(url);
if (response.statusCode == 200)
String data = response.body;
print(jsonDecode(data));
return jsonDecode(data);
else
print(response.statusCode);
print(response.body);
catch (e)
print("An error occurred: $e");
`
`
import 'package:flutter/material.dart';
import 'package:extension/extension.dart';
import 'package:mask_text_input_formatter/mask_text_input_formatter.dart';
import 'package:binlist/services/networking.dart';
String url = "https://lookup.binlist.net/$cardNumber";
String cardNumber = "";
String cardScheme = "-";
String cardType = "-";
String cardLength = "-";
String prepaid = "-";
String bankName = "-";
String countryName = "-";
class CardDetails extends StatefulWidget
@override
_CardDetailsState createState() => _CardDetailsState();
class _CardDetailsState extends State<CardDetails>
Future<dynamic> getCalledCardMetaData() async
BinDetails getBinDetails = BinDetails(url: url);
var cardMetaData = await getBinDetails.getCardMetadata();
if (cardMetaData['scheme'] == null)
setState(()
cardScheme = "-";
);
if (cardMetaData['type'] == null)
setState(()
cardType = "-";
);
if (cardMetaData['number']['length'] == null)
setState(()
cardLength = "-";
);
if (cardMetaData['prepaid'] == null)
setState(()
prepaid = "-";
);
if (cardMetaData['bank'] == null)
setState(()
bankName = "-";
);
if (cardMetaData['country'] == null)
setState(()
countryName = "-";
);
setState(()
cardScheme = cardMetaData['scheme'];
cardType = cardMetaData['type'];
cardLength = cardMetaData['number']['length'].toString();
if (cardLength == "null")
cardLength = "-";
prepaid = cardMetaData['prepaid'].toString();
if (prepaid == "false")
prepaid = "No";
else if (prepaid == "true")
prepaid = "Yes";
else if (prepaid == "null")
prepaid = "-";
bankName = cardMetaData['bank']['name'];
countryName = cardMetaData['country']['name'];
print(cardScheme);
print(countryName);
print(cardLength);
print(cardType);
print(bankName);
print(prepaid);
);
return cardMetaData;
final _imputedNumber = TextEditingController();
void clearCardNumber()
setState(()
_imputedNumber.clear();
cardScheme = "-";
cardType = "-";
cardLength = "-";
prepaid = "-";
bankName = "-";
countryName = "-";
print(cardNumber);
);
@override
Widget build(BuildContext context)
var maskFormatter = MaskTextInputFormatter(
mask: '#### ####', filter: "#": RegExp(r'[0-9]'));
return Scaffold(
appBar: AppBar(
title: Text(
'Bin List',
),
),
body: Column(
children: [
Expanded(
child: Column(
children: [
Container(
width: MediaQuery.of(context).size.width * 0.9,
child: TextField(
inputFormatters: [maskFormatter],
controller: _imputedNumber,
onChanged: (value)
String maskedNumber = value;
cardNumber =
maskedNumber.replaceAll(new RegExp(r'\s'), '');
print(cardNumber);
print(cardNumber.length);
if (cardNumber.length == 8)
getCalledCardMetaData();
,
keyboardType: TextInputType.number,
textAlign: TextAlign.center,
decoration: InputDecoration(
contentPadding: EdgeInsets.symmetric(horizontal: 5.0),
enabledBorder: UnderlineInputBorder(
borderSide: BorderSide(color: Colors.black54),
),
focusedBorder: UnderlineInputBorder(
borderSide:
BorderSide(color: Colors.lightBlue, width: 2.0),
),
suffix: TextButton(
onPressed: clearCardNumber,
child: Icon(
Icons.clear,
color: Colors.grey.shade600,
),
),
),
),
),`
我制作了一个应用程序,它使用 bin 列表 API (https://lookup.binlist.net/YOUR_CARD_NUMBER_HERE) 来获取卡片的元数据。当我从冷启动应用程序时,输入 CARD A 的卡号,并发出获取请求,我会取回卡元数据并用于更新 UI。当我清除 CARD A 的数字并为 CARD B 输入卡号时,我仍然得到 CARD A 而不是 CARD B 的元数据。但是当我再次从冷启动应用程序并输入 CARD B 的卡号时只有这样,我才能在 UI 上获得 CARD B 的正确元数据。
我试图通过在 TextField 的值发生变化时将卡号打印到控制台来进行调试。我输入了正确的数字,这个输入的数字是发送到 API 的,但是第二张卡的元数据没有从 API 中检索到。我每次都必须从冷启动应用程序以检索正确的元数据。我能做些什么来解决这个问题?谢谢。
[
【问题讨论】:
【参考方案1】:在评估所有条件后,在您的代码中,尝试在调用 getCalledCardMetaData() 之前调用清除先前值的函数。
if (cardNumber.length == 8)
clearCardNumber();
getCalledCardMetaData();
【讨论】:
这并不能解决问题。它在调用 API 之前清除卡号,当我点击它时,取消图标也会这样做以上是关于Flutter - 多次调用 API 并使用从互联网返回的更改更新 UI的主要内容,如果未能解决你的问题,请参考以下文章
Flutter:如何在加载页面之前从 Api 获取数据 [关闭]