如何从initState调用json并设置数据并使用另一个小部件?

时间:2018-05-15 11:52:26

标签: json widget flutter

在initState中调用我的json无效。尝试从Future setState设置数据,仍然无法工作。

我有一个从我的json获取数据的小部件。我添加完整的代码。希望得到一些帮助。

我尝试按照其他例子,似乎我做不到。我的问题是我试图在构建小部件之前设置json数据并尝试从其他小部件访问数据。

任何帮助将不胜感激。

    /*

My Json Data

{ 
   "date":"20180515",
   "currency":{ 
      "dollar":{ 
         "buy":"4,3600",
         "sell":"4,4600",
      },
      "sterling":{ 
         "buy":"5,9350",
         "sell":"6,0350",
      },
      "euro":{ 
         "buy":"5,2150",
         "sell":"5,3150",
      }
   }
}

*/

import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'dart:async';
import 'dart:convert';
import 'package:http/http.dart' as http;
import 'dart:math';

final Color darkMainGreen = const Color(0xFF689F38);
final Color midMainGreen = const Color(0xFF7CB342);
final Color lightMainGreen = const Color(0xFF8BC34A);

var currencyData;
var stgBuy;
var stgSell;
var eurBuy;
var eurSell;
var usdBuy;
var usdSell;

// TODO: 1) MAIN
void main() async {
  runApp(new MyApp());
}

// TODO: 2) MyApp
class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      debugShowCheckedModeBanner: false,
      title: "MyDepo",
      home: new MyHomePage(title: "MyDepo"),
    );
  }
}

// TODO: 3) Statefull MyHomePage Class
class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);
  final String title;

  @override
  _MyHomePageState createState() => new _MyHomePageState();
}

// TODO: 4) _MyHomePageState Class
class _MyHomePageState extends State<MyHomePage> {
  @override
  void initState() {
    this.getCurrencyJsonData();
  }

  // JSON: GET CURRENCY
  Future<String> getCurrencyJsonData() async {
    var response = await http.get(
        Uri.encodeFull("******* myJsonData *********"),
        headers: {'Accept': 'application/json'});

    this.setState(() {
      currencyData = json.decode(response.body);
      var stgBuy = currencyData["currency"]["sterling"]["buy"];
      var stgSell = currencyData["currency"]["sterling"]["sell"];
      var eurBuy = currencyData["currency"]["euro"]["buy"];
      var eurSell = currencyData["currency"]["euro"]["sell"];
      var usdBuy = currencyData["currency"]["dollar"]["buy"];
      var usdSell = currencyData["currency"]["dollar"]["sell"];
    });

    return "Success!";
  }

// TODO: BUILD WIDGET
  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      // APPBAR
      appBar: new AppBar(
        title: new Text(
          "MyDepo",
          style: TextStyle(fontSize: 18.0, fontWeight: FontWeight.w500),
        ),
        //elevation: 1.0,
        backgroundColor: midMainGreen,
      ),

      // BODY
      body: new ListView(
        padding: const EdgeInsets.all(0.0),
        children: <Widget>[
          new Padding(padding: EdgeInsets.fromLTRB(3.0, 4.0, 3.0, 4.0)),
          new CurrencyCard(),
        ],
      ),
    );
  } // build Widget

} // _MyHomePageState Class

class CurrencyCard extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // RED
    final redGradient = const LinearGradient(
        colors: const <Color>[const Color(0xFFBA110E), const Color(0xFFCF3110)],
        stops: const <double>[0.4, 0.6],
        begin: Alignment.topRight,
        end: Alignment.bottomLeft);

    // BLUE
    final blueGraient = const LinearGradient(
        colors: const <Color>[const Color(0xFF0075D1), const Color(0xFF00A2E3)],
        stops: const <double>[0.5, 0.7],
        begin: Alignment.topLeft,
        end: Alignment.bottomRight);

    // GREEN
    final greenGradient = const LinearGradient(colors: const <Color>[
      const Color(0xFF7CB342), //const Color(0xFF87AE0C),
      const Color(0xFF8BC34A), //const Color(0xFF97C40C),
    ], stops: const <double>[
      0.6,
      0.8
    ], begin: Alignment.bottomRight, end: Alignment.topLeft);

    return new Container(
      constraints: const BoxConstraints(maxHeight: 90.0),
      margin: const EdgeInsets.all(10.0),
      child: new Align(
        alignment: Alignment.center,
        child: new ListView(
            shrinkWrap: true,
            scrollDirection: Axis.horizontal,
            children: <Widget>[
              _buildAction(
                  "£ Sterling",
                  "Buy: ",
                  stgBuy,
                  "Sell: ",
                  stgSell,
                  Colors.red,
                  redGradient,
                  new AssetImage("assets/images/dollar.png")),
              _buildAction(
                  "€ Euro",
                  "Buy: ",
                  stgBuy,
                  "Sell: ",
                  stgSell,
                  Colors.blue,
                  blueGraient,
                  new AssetImage("assets/images/euro.png")),
              _buildAction(
                  "\$ Dollar",
                  "Buy: ",
                  stgBuy,
                  "Sell: ",
                  stgSell,
                  Colors.green,
                  greenGradient,
                  new AssetImage("assets/images/sterling.png")),
            ]),
      ),
    );
  }

  Widget _buildAction(
      String title,
      String titleAlis,
      String titleAlisValue,
      String titleSatis,
      String titleSatisValue,
      Color color,
      Gradient gradient,
      ImageProvider backgroundImage) {
    return new GestureDetector(
      child: new Container(
        margin: const EdgeInsets.only(right: 5.0, left: 5.0),
        width: 150.0,
        decoration: new BoxDecoration(
            color: color,
            shape: BoxShape.rectangle,
            borderRadius: new BorderRadius.circular(10.0),
            boxShadow: <BoxShadow>[
              new BoxShadow(
                  color: Colors.black38,
                  blurRadius: 2.0,
                  spreadRadius: 1.0,
                  offset: new Offset(0.0, 1.0)),
            ],
            gradient: gradient),
        child: new Stack(
          children: <Widget>[
            new Opacity(
              opacity: 0.3,
              child: new Align(
                alignment: Alignment.centerRight,
                child: new Transform.rotate(
                  angle: -pi / 4.8,
                  alignment: Alignment.centerRight,
                  child: new ClipPath(
                    child: new Container(
                      padding: const EdgeInsets.only(
                          bottom: 15.0, right: 0.0, left: 60.0),
                      child: new Image(
                        width: 90.0,
                        height: 90.0,
                        image: backgroundImage != null
                            ? backgroundImage
                            : new AssetImage("assets/images/wallet.png"),
                      ),
                    ),
                  ),
                ),
              ),
            ), // END BACKGROUND IMAGE

            new Container(
              padding: EdgeInsets.all(5.0),
              child: new Column(
                children: <Widget>[
                  new Column(
                    children: <Widget>[
                      new Row(
                        children: <Widget>[
                          new Padding(padding: EdgeInsets.all(3.0)),
                          // TITLE (£ Sterling, € Euro, $ Dollar)
                          new Text(
                            title,
                            style: TextStyle(
                                color: Colors.white,
                                fontSize: 16.0,
                                fontWeight: FontWeight.w800),
                          )
                        ],
                      )
                    ],
                  ),
                  new Padding(padding: EdgeInsets.all(4.0)),
                  new Column(
                    crossAxisAlignment: CrossAxisAlignment.center,
                    children: <Widget>[
                      new Row(
                        mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                        children: <Widget>[
                          new Text(
                            titleAlis,
                            style: TextStyle(
                                color: Colors.white,
                                fontSize: 15.0,
                                fontWeight: FontWeight.w900),
                          ),
                          new Divider(),
                          new Text(
                            titleAlisValue,
                            style: TextStyle(
                                color: Colors.white,
                                fontSize: 14.0,
                                fontWeight: FontWeight.w400),
                          ),
                        ],
                      )
                    ],
                  ),
                  new Padding(padding: EdgeInsets.all(4.0)),
                  new Column(
                    crossAxisAlignment: CrossAxisAlignment.center,
                    children: <Widget>[
                      new Row(
                        mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                        children: <Widget>[
                          new Text(
                            titleSatis,
                            style: TextStyle(
                                color: Colors.white,
                                fontSize: 15.0,
                                fontWeight: FontWeight.w900),
                          ),
                          new Divider(),
                          new Text(
                            titleSatisValue,
                            style: TextStyle(
                                color: Colors.white,
                                fontSize: 14.0,
                                fontWeight: FontWeight.w400),
                          ),
                        ],
                      )
                    ],
                  ),
                ],
              ),
            )
          ],
        ),
      ),
    );
  }
}

2 个答案:

答案 0 :(得分:0)

.site-nav-desktop__item:last-child { a { span::after { display: none; } padding-right: 0; } margin-right: 0; } 中的变量再次声明,因此只有一个局部范围。 Dart正在自下而上搜索变量声明,因此这些声明会覆盖此范围内的全局变量。

setState()

解决问题的最简单方法可能是从var currencyData; var stgBuy; var stgSell; var eurBuy; var eurSell; var usdBuy; var usdSell; [...] this.setState(() { currencyData = json.decode(response.body); var stgBuy = currencyData["currency"]["sterling"]["buy"]; var stgSell = currencyData["currency"]["sterling"]["sell"]; var eurBuy = currencyData["currency"]["euro"]["buy"]; var eurSell = currencyData["currency"]["euro"]["sell"]; var usdBuy = currencyData["currency"]["dollar"]["buy"]; var usdSell = currencyData["currency"]["dollar"]["sell"]; }); - 方法中的变量中删除var,以将值分配给全局变量。

但整个方法都值得怀疑,我建议你,例如为此使用setState()的成员变量,并将它们作为constuctor args传递给_MyHomePageState,至少清理一下。

答案 1 :(得分:0)

对于异步函数,您也可以像这样初始化状态:

  @override
  void initState() {
    super.initState();
    getCurrencyJsonData().then((result) {
      setState(() {
        print('Data Loaded');
      });
    });
  }