Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/dart/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Flutter 使用Dart从API获取数据时出现的问题_Flutter_Dart - Fatal编程技术网

Flutter 使用Dart从API获取数据时出现的问题

Flutter 使用Dart从API获取数据时出现的问题,flutter,dart,Flutter,Dart,我的应用程序有问题,我正在创建一个flutter应用程序来跟踪加密货币的价格。 问题是,我正确地从API获取数据,然后将其打印到Advisor中,但当我尝试在应用程序中显示它时,它显示为null 下面是我用来从API获取数据的代码 class CurrencyData { var decodedData; Future getCoinsData() async { http.Response response = await http.get(coinUrl); if (respon

我的应用程序有问题,我正在创建一个flutter应用程序来跟踪加密货币的价格。 问题是,我正确地从API获取数据,然后将其打印到Advisor中,但当我尝试在应用程序中显示它时,它显示为null

下面是我用来从API获取数据的代码

class CurrencyData { var decodedData;
Future getCoinsData() async {

http.Response response =
    await http.get(coinUrl);

if (response.statusCode == 200) {
  decodedData = jsonDecode(response.body);
} else {
  print(response.statusCode);
  throw 'Problem with the request, try again later!';
}
return decodedData;
}
}
这是我调用数据以显示数据的代码。

class _DashboardPageState extends State<DashboardPage> {
CurrencyData currencyData = CurrencyData();
  var btcPrice;
  var btcChange24h;
void cryptoCurrencyData() async {
    var data = await currencyData.getCoinsData();
print(btcPrice = data['data'][0]['priceUsd']);
print(btcChange24h = data['data'][0]['changePercent24Hr']);
}
@override
  void initState() {
super.initState();
cryptoCurrencyData();
}
  @override
  Widget build(BuildContext context) {
return Scaffold(
  body: SafeArea(
child: ListView(
  children: <Widget>[
Column(
  children: <Widget>[
        // the top bar
            Container(
              padding: EdgeInsets.all(40),
              constraints: BoxConstraints.expand(height: 175),
              decoration: BoxDecoration(
                color: Colors.lightBlue,
                boxShadow: [
                  BoxShadow(
                    color: Colors.black26,
                    blurRadius: 20.0,
                    // has the effect of softening the shadow
                    spreadRadius:
                        5.0, // has the effect of extending the shadow
                  ),
                ],
                borderRadius: BorderRadius.only(
                  bottomLeft: Radius.circular(30),
                  bottomRight: Radius.circular(30),
                ),
              ),
              child: Container(
                padding: EdgeInsets.only(top: 25),
                child: Column(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: <Widget>[
                    Center(
                      child: Text(
                        'Crypto Tracker',
                        textAlign: TextAlign.center,
                        style: TextStyle(
                          color: Colors.white,
                          fontSize: 30.0,
                          fontWeight: FontWeight.bold,
                        ),
                      ),
                    )
                  ],
                ),
              ),
            ),
            // the body part
            CurrencyWidget(
              currencyIconUrl: 'assets/images/btc.png',
              currencyName: 'Bitcoin',
              currencyShortName: 'BTC',
              currencyPrice: btcPrice,
              currencyChange24h: btcChange24h,
            ),
class\u仪表板页面状态扩展状态{
CurrencyData CurrencyData=CurrencyData();
var-btcPrice;
var btcChange24h;
void cryptoCurrencyData()异步{
var data=await currencyData.getCoinsData();
打印(btcPrice=data['data'][0]['priceUsd']);
打印(btcChange24h=data['data'][0]['ChangePercents24hr']);
}
@凌驾
void initState(){
super.initState();
cryptoCurrencyData();
}
@凌驾
小部件构建(构建上下文){
返回脚手架(
正文:安全区(
子:ListView(
儿童:[
纵队(
儿童:[
//顶栏
容器(
填充:边缘设置。全部(40),
约束:BoxConstraints.expand(高度:175),
装饰:盒子装饰(
颜色:颜色。浅蓝色,
boxShadow:[
箱形阴影(
颜色:颜色。黑色,
半径:20.0,
//具有软化阴影的效果
扩展半径:
5.0,//具有扩展阴影的效果
),
],
borderRadius:仅限borderRadius(
左下角:半径。圆形(30),
右下角:半径。圆形(30),
),
),
子:容器(
填充:仅限边缘设置(顶部:25),
子:列(
crossAxisAlignment:crossAxisAlignment.start,
儿童:[
居中(
子:文本(
“加密跟踪器”,
textAlign:textAlign.center,
样式:TextStyle(
颜色:颜色,白色,
字体大小:30.0,
fontWeight:fontWeight.bold,
),
),
)
],
),
),
),
//身体部位
CurrencyWidget(
currenciconurl:'assets/images/btc.png',
currencyName:“比特币”,
currencyShortName:'BTC',
当前价格:btcPrice,
电流变化24小时:BTCChange24小时,
),
我将数据打印到控制台中,但在模拟器中也会显示Null,如下面的屏幕截图所示


知道问题是什么吗?

问题是获取api数据是一项异步任务,因此需要花费时间,而构建方法构建屏幕在这段时间内,因此打印为空

1) 您可以在函数末尾调用setState,当它从API获取时,该函数会将null更改为实际数据

void cryptoCurrencyData() async {
    var data = await currencyData.getCoinsData();
    btcPrice = data['data'][0]['priceUsd'];  // assign
    btcChange24h = data['data'][0]['changePercent24Hr']; // aasign
   print(btcPrice = data['data'][0]['priceUsd']);
   print(btcChange24h = data['data'][0]['changePercent24Hr']);
      setState(() {}); // added
   }
2) 不过,FutureBuilder是一个更好的选项,您可以在其中显示加载指示器或显示数据正在加载并在到达时显示的内容

注意:这样您就不需要cryptoCurrencyData方法,也不需要将值存储在不同的变量中

FutureBuilder(
        future: currencyData.getCoinsData(),
        builder: (_, sanpshot) {
          if (!sanpshot.hasData) {
            return CircularProgressIndicator();
          }
          return CurrencyWidget(
            currencyIconUrl: 'assets/images/btc.png',
            currencyName: 'Bitcoin',
            currencyShortName: 'BTC',
            currencyPrice: data['data'][0]['priceUsd'],
            currencyChange24h: data['data'][0]['changePercent24Hr'],
          );
        },
      ),

问题是获取api数据是一项异步任务,因此需要时间,而构建方法构建屏幕在这段时间内显示,因此打印空值

1) 您可以在函数末尾调用setState,当它从API获取时,该函数会将null更改为实际数据

void cryptoCurrencyData() async {
    var data = await currencyData.getCoinsData();
    btcPrice = data['data'][0]['priceUsd'];  // assign
    btcChange24h = data['data'][0]['changePercent24Hr']; // aasign
   print(btcPrice = data['data'][0]['priceUsd']);
   print(btcChange24h = data['data'][0]['changePercent24Hr']);
      setState(() {}); // added
   }
2) 不过,FutureBuilder是一个更好的选项,您可以在其中显示加载指示器或显示数据正在加载并在到达时显示的内容

注意:这样您就不需要cryptoCurrencyData方法,也不需要将值存储在不同的变量中

FutureBuilder(
        future: currencyData.getCoinsData(),
        builder: (_, sanpshot) {
          if (!sanpshot.hasData) {
            return CircularProgressIndicator();
          }
          return CurrencyWidget(
            currencyIconUrl: 'assets/images/btc.png',
            currencyName: 'Bitcoin',
            currencyShortName: 'BTC',
            currencyPrice: data['data'][0]['priceUsd'],
            currencyChange24h: data['data'][0]['changePercent24Hr'],
          );
        },
      ),

非常感谢,设置状态选项很好,我将继续使用它,因为我仍然是初学者,不熟悉FutureBuilder。但是,我今天将学习它。谢谢:)很高兴听到它对您有用。您发现我的答案很有用,然后接受它,这样其他社区成员也可以受益。非常感谢您,设置状态选项w工作很好,我会继续学习,因为我还是初学者,不熟悉FutureBuilder。但是,我今天会学习它。谢谢:)很高兴听到它对你有用。你发现我的答案很有用,然后接受它,这样其他社区成员也可以受益。