如何在 Flutter 中使用 CoinMarketCap API
Posted
技术标签:
【中文标题】如何在 Flutter 中使用 CoinMarketCap API【英文标题】:How to use CoinMarketCap API in flutter 【发布时间】:2020-09-19 06:16:00 【问题描述】:我正在关注一个显示加密货币价格的应用教程,但我在使用新 API 时遇到了问题。下面的代码只是来自教程,导师使用的是旧的 coinmarketcap API。 Coinmarketcap 已迁移到新的,您需要注册以获得免费的 API 密钥。新 API 的文档:https://coinmarketcap.com/api/documentation/v1。
我想我需要将 _apiURL 更改为 https://pro-api.coinmarketcap.com/v1/cryptocurrency/listings/latest?start=1&limit=5000&convert=USD 并以某种方式使用 APIKey。有没有人有办法解决吗?对颤振和 API 来说还是有点新,所以如果这个问题很难回答,我很抱歉。
Future<void> getCryptoPrices() async
//async to use await, which suspends the current function, while it does other stuff and resumes when data ready
print('getting crypto prices'); //print
String _apiURL =
"https://api.coinmarketcap.com/v1/ticker/"; //url to get data
setState(()
this._loading = true; //before calling the api, set the loading to true
);
http.Response response = await http.get(_apiURL); //waits for response
setState(()
this._cryptoList =
jsonDecode(response.body); //sets the state of our widget
this._loading = false; //set the loading to false after we get a response
print(_cryptoList); //prints the list
);
return;
【问题讨论】:
【参考方案1】:您可以在下面复制粘贴运行完整代码并在运行前替换your-key
您可以将API key
放入headers
并使用payloadFromJson
解析json 响应并使用FutureBuilder
显示
您可以在完整代码中查看 Payload 类定义
Future<Payload> getCryptoPrices() async
var response = await http.get(
"https://pro-api.coinmarketcap.com/v1/cryptocurrency/listings/latest?start=1&limit=5000&convert=USD",
headers:
'X-CMC_PRO_API_KEY': 'your-key',
"Accept": "application/json",
);
if (response.statusCode == 200)
return payloadFromJson(response.body);
工作演示
完整代码
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'dart:convert';
Payload payloadFromJson(String str) => Payload.fromJson(json.decode(str));
String payloadToJson(Payload data) => json.encode(data.toJson());
class Payload
Payload(
this.status,
this.data,
);
Status status;
List<Datum> data;
factory Payload.fromJson(Map<String, dynamic> json) => Payload(
status: Status.fromJson(json["status"]),
data: List<Datum>.from(json["data"].map((x) => Datum.fromJson(x))),
);
Map<String, dynamic> toJson() =>
"status": status.toJson(),
"data": List<dynamic>.from(data.map((x) => x.toJson())),
;
class Datum
Datum(
this.id,
this.name,
this.symbol,
this.slug,
this.numMarketPairs,
this.dateAdded,
this.tags,
this.maxSupply,
this.circulatingSupply,
this.totalSupply,
this.platform,
this.cmcRank,
this.lastUpdated,
this.quote,
);
int id;
String name;
String symbol;
String slug;
int numMarketPairs;
DateTime dateAdded;
List<Tag> tags;
double maxSupply;
double circulatingSupply;
double totalSupply;
Platform platform;
int cmcRank;
DateTime lastUpdated;
Quote quote;
factory Datum.fromJson(Map<String, dynamic> json) => Datum(
id: json["id"],
name: json["name"],
symbol: json["symbol"],
slug: json["slug"],
numMarketPairs: json["num_market_pairs"],
dateAdded: DateTime.parse(json["date_added"]),
tags: List<Tag>.from(json["tags"].map((x) => tagValues.map[x])),
maxSupply:
json["max_supply"] == null ? null : json["max_supply"].toDouble(),
circulatingSupply: json["circulating_supply"] == null
? null
: json["circulating_supply"].toDouble(),
totalSupply: json["total_supply"] == null
? null
: json["total_supply"].toDouble(),
platform: json["platform"] == null
? null
: Platform.fromJson(json["platform"]),
cmcRank: json["cmc_rank"],
lastUpdated: DateTime.parse(json["last_updated"]),
quote: Quote.fromJson(json["quote"]),
);
Map<String, dynamic> toJson() =>
"id": id,
"name": name,
"symbol": symbol,
"slug": slug,
"num_market_pairs": numMarketPairs,
"date_added": dateAdded.toIso8601String(),
"tags": List<dynamic>.from(tags.map((x) => tagValues.reverse[x])),
"max_supply": maxSupply == null ? null : maxSupply,
"circulating_supply":
circulatingSupply == null ? null : circulatingSupply,
"total_supply": totalSupply == null ? null : totalSupply,
"platform": platform == null ? null : platform.toJson(),
"cmc_rank": cmcRank,
"last_updated": lastUpdated.toIso8601String(),
"quote": quote.toJson(),
;
class Platform
Platform(
this.id,
this.name,
this.symbol,
this.slug,
this.tokenAddress,
);
int id;
Name name;
Symbol symbol;
Slug slug;
String tokenAddress;
factory Platform.fromJson(Map<String, dynamic> json) => Platform(
id: json["id"],
name: nameValues.map[json["name"]],
symbol: symbolValues.map[json["symbol"]],
slug: slugValues.map[json["slug"]],
tokenAddress: json["token_address"],
);
Map<String, dynamic> toJson() =>
"id": id,
"name": nameValues.reverse[name],
"symbol": symbolValues.reverse[symbol],
"slug": slugValues.reverse[slug],
"token_address": tokenAddress,
;
enum Name
ETHEREUM,
TRON,
OMNI,
RSK_SMART_BITCOIN,
BINANCE_COIN,
STELLAR,
NEO,
V_SYSTEMS,
ARDOR,
QTUM,
XRP,
WAVES,
ONTOLOGY,
EOS,
NEBULAS,
NEM,
BIT_SHARES,
BITCOIN_CASH,
INT_CHAIN,
COSMOS,
UBIQ,
VE_CHAIN,
NU_BITS,
PIVX,
COUNTERPARTY,
KOMODO,
ICON,
GX_CHAIN,
VITE,
WANCHAIN,
iosT,
TRUE_CHAIN,
ETHEREUM_CLASSIC
final nameValues = EnumValues(
"Ardor": Name.ARDOR,
"Binance Coin": Name.BINANCE_COIN,
"Bitcoin Cash": Name.BITCOIN_CASH,
"BitShares": Name.BIT_SHARES,
"Cosmos": Name.COSMOS,
"Counterparty": Name.COUNTERPARTY,
"EOS": Name.EOS,
"Ethereum": Name.ETHEREUM,
"Ethereum Classic": Name.ETHEREUM_CLASSIC,
"GXChain": Name.GX_CHAIN,
"ICON": Name.ICON,
"INT Chain": Name.INT_CHAIN,
"IOST": Name.IOST,
"Komodo": Name.KOMODO,
"Nebulas": Name.NEBULAS,
"NEM": Name.NEM,
"Neo": Name.NEO,
"NuBits": Name.NU_BITS,
"Omni": Name.OMNI,
"Ontology": Name.ONTOLOGY,
"PIVX": Name.PIVX,
"Qtum": Name.QTUM,
"RSK Smart Bitcoin": Name.RSK_SMART_BITCOIN,
"Stellar": Name.STELLAR,
"TRON": Name.TRON,
"TrueChain": Name.TRUE_CHAIN,
"Ubiq": Name.UBIQ,
"VeChain": Name.VE_CHAIN,
"VITE": Name.VITE,
"v.systems": Name.V_SYSTEMS,
"Wanchain": Name.WANCHAIN,
"Waves": Name.WAVES,
"XRP": Name.XRP
);
enum Slug
ETHEREUM,
TRON,
OMNI,
RSK_SMART_BITCOIN,
BINANCE_COIN,
STELLAR,
NEO,
V_SYSTEMS,
ARDOR,
QTUM,
XRP,
WAVES,
ONTOLOGY,
EOS,
NEBULAS_TOKEN,
NEM,
BITSHARES,
BITCOIN_CASH,
INT_CHAIN,
COSMOS,
UBIQ,
VECHAIN,
NUBITS,
PIVX,
COUNTERPARTY,
KOMODO,
ICON,
GXCHAIN,
VITE,
WANCHAIN,
IOSTOKEN,
TRUECHAIN,
ETHEREUM_CLASSIC
final slugValues = EnumValues(
"ardor": Slug.ARDOR,
"binance-coin": Slug.BINANCE_COIN,
"bitcoin-cash": Slug.BITCOIN_CASH,
"bitshares": Slug.BITSHARES,
"cosmos": Slug.COSMOS,
"counterparty": Slug.COUNTERPARTY,
"eos": Slug.EOS,
"ethereum": Slug.ETHEREUM,
"ethereum-classic": Slug.ETHEREUM_CLASSIC,
"gxchain": Slug.GXCHAIN,
"icon": Slug.ICON,
"int-chain": Slug.INT_CHAIN,
"iostoken": Slug.IOSTOKEN,
"komodo": Slug.KOMODO,
"nebulas-token": Slug.NEBULAS_TOKEN,
"nem": Slug.NEM,
"neo": Slug.NEO,
"nubits": Slug.NUBITS,
"omni": Slug.OMNI,
"ontology": Slug.ONTOLOGY,
"pivx": Slug.PIVX,
"qtum": Slug.QTUM,
"rsk-smart-bitcoin": Slug.RSK_SMART_BITCOIN,
"stellar": Slug.STELLAR,
"tron": Slug.TRON,
"truechain": Slug.TRUECHAIN,
"ubiq": Slug.UBIQ,
"vechain": Slug.VECHAIN,
"vite": Slug.VITE,
"v-systems": Slug.V_SYSTEMS,
"wanchain": Slug.WANCHAIN,
"waves": Slug.WAVES,
"xrp": Slug.XRP
);
enum Symbol
ETH,
TRX,
OMNI,
RBTC,
BNB,
XLM,
NEO,
VSYS,
ARDR,
QTUM,
XRP,
WAVES,
ONT,
EOS,
NAS,
XEM,
BTS,
BCH,
INT,
ATOM,
UBQ,
VET,
USNBT,
PIVX,
XCP,
KMD,
ICX,
GXC,
VITE,
WAN,
IOST,
TRUE,
ETC
final symbolValues = EnumValues(
"ARDR": Symbol.ARDR,
"ATOM": Symbol.ATOM,
"BCH": Symbol.BCH,
"BNB": Symbol.BNB,
"BTS": Symbol.BTS,
"EOS": Symbol.EOS,
"ETC": Symbol.ETC,
"ETH": Symbol.ETH,
"GXC": Symbol.GXC,
"ICX": Symbol.ICX,
"INT": Symbol.INT,
"IOST": Symbol.IOST,
"KMD": Symbol.KMD,
"NAS": Symbol.NAS,
"NEO": Symbol.NEO,
"OMNI": Symbol.OMNI,
"ONT": Symbol.ONT,
"PIVX": Symbol.PIVX,
"QTUM": Symbol.QTUM,
"RBTC": Symbol.RBTC,
"TRUE": Symbol.TRUE,
"TRX": Symbol.TRX,
"UBQ": Symbol.UBQ,
"USNBT": Symbol.USNBT,
"VET": Symbol.VET,
"VITE": Symbol.VITE,
"VSYS": Symbol.VSYS,
"WAN": Symbol.WAN,
"WAVES": Symbol.WAVES,
"XCP": Symbol.XCP,
"XEM": Symbol.XEM,
"XLM": Symbol.XLM,
"XRP": Symbol.XRP
);
class Quote
Quote(
this.usd,
);
Usd usd;
factory Quote.fromJson(Map<String, dynamic> json) => Quote(
usd: Usd.fromJson(json["USD"]),
);
Map<String, dynamic> toJson() =>
"USD": usd.toJson(),
;
class Usd
Usd(
this.price,
this.volume24H,
this.percentChange1H,
this.percentChange24H,
this.percentChange7D,
this.marketCap,
this.lastUpdated,
);
double price;
double volume24H;
double percentChange1H;
double percentChange24H;
double percentChange7D;
double marketCap;
DateTime lastUpdated;
factory Usd.fromJson(Map<String, dynamic> json) => Usd(
price: json["price"] == null ? null : json["price"].toDouble(),
volume24H:
json["volume_24h"] == null ? null : json["volume_24h"].toDouble(),
percentChange1H: json["percent_change_1h"] == null
? null
: json["percent_change_1h"].toDouble(),
percentChange24H: json["percent_change_24h"] == null
? null
: json["percent_change_24h"].toDouble(),
percentChange7D: json["percent_change_7d"] == null
? null
: json["percent_change_7d"].toDouble(),
marketCap:
json["market_cap"] == null ? null : json["market_cap"].toDouble(),
lastUpdated: DateTime.parse(json["last_updated"]),
);
Map<String, dynamic> toJson() =>
"price": price == null ? null : price,
"volume_24h": volume24H == null ? null : volume24H,
"percent_change_1h": percentChange1H == null ? null : percentChange1H,
"percent_change_24h":
percentChange24H == null ? null : percentChange24H,
"percent_change_7d": percentChange7D == null ? null : percentChange7D,
"market_cap": marketCap == null ? null : marketCap,
"last_updated": lastUpdated.toIso8601String(),
;
enum Tag MINEABLE
final tagValues = EnumValues("mineable": Tag.MINEABLE);
class Status
Status(
this.timestamp,
this.errorCode,
this.errorMessage,
this.elapsed,
this.creditCount,
this.notice,
);
DateTime timestamp;
int errorCode;
dynamic errorMessage;
int elapsed;
int creditCount;
dynamic notice;
factory Status.fromJson(Map<String, dynamic> json) => Status(
timestamp: DateTime.parse(json["timestamp"]),
errorCode: json["error_code"],
errorMessage: json["error_message"],
elapsed: json["elapsed"],
creditCount: json["credit_count"],
notice: json["notice"],
);
Map<String, dynamic> toJson() =>
"timestamp": timestamp.toIso8601String(),
"error_code": errorCode,
"error_message": errorMessage,
"elapsed": elapsed,
"credit_count": creditCount,
"notice": notice,
;
class EnumValues<T>
Map<String, T> map;
Map<T, String> reverseMap;
EnumValues(this.map);
Map<T, String> get reverse
if (reverseMap == null)
reverseMap = map.map((k, v) => new MapEntry(v, k));
return reverseMap;
void main()
runApp(MyApp());
class MyApp extends StatelessWidget
@override
Widget build(BuildContext context)
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
class MyHomePage extends StatefulWidget
MyHomePage(Key key, this.title) : super(key: key);
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
class _MyHomePageState extends State<MyHomePage>
int _counter = 0;
Future<Payload> _future;
Future<Payload> getCryptoPrices() async
var response = await http.get(
"https://pro-api.coinmarketcap.com/v1/cryptocurrency/listings/latest?start=1&limit=5000&convert=USD",
headers:
'X-CMC_PRO_API_KEY': 'your-key',
"Accept": "application/json",
);
if (response.statusCode == 200)
return payloadFromJson(response.body);
@override
void initState()
// TODO: implement initState
super.initState();
_future = getCryptoPrices();
@override
Widget build(BuildContext context)
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: FutureBuilder(
future: _future,
builder: (context, AsyncSnapshot<Payload> snapshot)
switch (snapshot.connectionState)
case ConnectionState.none:
return Text('none');
case ConnectionState.waiting:
return Center(child: CircularProgressIndicator());
case ConnectionState.active:
return Text('');
case ConnectionState.done:
if (snapshot.hasError)
return Text(
'$snapshot.error',
style: TextStyle(color: Colors.red),
);
else
return ListView.builder(
itemCount: snapshot.data.data.length,
itemBuilder: (context, index)
return Card(
elevation: 6.0,
child: Padding(
padding: const EdgeInsets.only(
top: 6.0,
bottom: 6.0,
left: 8.0,
right: 8.0),
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(snapshot.data.data[index].name),
Spacer(),
Text(snapshot.data.data[index].lastUpdated
.toIso8601String()),
Spacer(),
Text(
snapshot.data.data[index].quote.usd.price
.toString(),
),
],
),
));
);
));
【讨论】:
从 API 中获取徽标是否也很困难? 我在 API 响应中没有看到徽标字段名称。是 png 还是 jpeg。 coinmarketcap.com/api/documentation/v1/#operation/…。 “徽标”下的 PNG。以上是关于如何在 Flutter 中使用 CoinMarketCap API的主要内容,如果未能解决你的问题,请参考以下文章
Flutter-如何在flutter的整个应用程序生命周期中将数据保存在内存中?
如何在 Flutter 中使用 GestureDetector 隐藏 appBar?
如何在 Flutter 的原生 C++ 中使用 OpenCV 4(2021 年)(支持 Flutter 2.0)? [关闭]
如何在 Dart / Flutter 中使用另一个文件的函数?
在 Flutter 中,我们如何使用 Firebase Messaging onBackgroundMessage 创建通知,使用flutter_local_notifications?