Flutter-使用Future加载本地JSON时设置加载动画

时间:2019-11-23 11:58:04

标签: json flutter

我正在尝试在加载本地JSON文件时实现加载动画逻辑(可能是循环进度指示器)。我为此使用了flutter的未来,但找不到合适的方法。

我有一个对象[id: int, country: String, state: String]的列表,并且一次在卡中显示一个对象,并且最终结果应该只是第一次循环执行

到目前为止,这是我的代码:

class _BottomCardsState extends State<BottomCards>{
  Future<Null> getAllData() async{
    var response = await DefaultAssetBundle.of(context).loadString('assets/json/data.json');
    var decodedData = json.decode(response);
    setState(() {
      for(Map element in decodedData){
        mDataList.add(Country.fromJson(element));
      }
    });
  }

  @override
  void initState() {
    super.initState();
    getAllData();
  }

  int index = mDataList.first.id;

  @override
  Widget build(BuildContext context) {
    int n = mDataList[index].id;
    return Container(
      child: Material(
        color: Colors.transparent,
        child: Card(
          margin: EdgeInsets.symmetric(horizontal: 10.0),
          elevation: 6.0,
          child: Container(
            alignment: Alignment.topCenter,
            padding: EdgeInsets.symmetric(horizontal: 12.0,),
            child: Column(
                Row(
                  mainAxisAlignment: MainAxisAlignment.start,
                  mainAxisSize: MainAxisSize.max,
                  children: <Widget>[
                    Column(                  
                      children: <Widget>[
                        Text(mDataList[index].country + ' ' + mDataList[index].state),
                      ],
                    ),
                  ],
                ),                  
                SizedBox(height: 8.0,),
                Row(
                  mainAxisAlignment: MainAxisAlignment.end,
                  mainAxisSize: MainAxisSize.max,
                  children: <Widget>[
                    Chip(
                      backgroundColor: secondaryDark,
                      label: Text('Info number: $n'),
                    ),
                  ],
                ),
                SizedBox(height: 6.0),
              ],
            ),
          ),
        ),
      ),
    );
  }
}

2 个答案:

答案 0 :(得分:0)

尝试使用FutureBuilder。它看起来应该像这样:

class _BottomCardsState extends State<BottomCards> {
  @override
  Widget build(BuildContext context) {
    return FutureBuilder(
      builder: (context, snapshot) {
        if (snapshot.hasData) {
          var decodedData = json.decode(snapshot.data);
          for(Map element in decodedData){
            mDataList.add(Country.fromJson(element));
          }
          int index = mDataList.first.id;
          int n = mDataList[index].id;

          return Container(
            child: Material(
              color: Colors.transparent,
              child: Card(
                margin: EdgeInsets.symmetric(horizontal: 10.0),
                elevation: 6.0,
                child: Container(
                  alignment: Alignment.topCenter,
                  padding: EdgeInsets.symmetric(
                    horizontal: 12.0,
                  ),
                  child: Column(
                    children: [
                      Row(
                        mainAxisAlignment: MainAxisAlignment.start,
                        mainAxisSize: MainAxisSize.max,
                        children: <Widget>[
                          Column(
                            children: <Widget>[
                              Text(mDataList[index].country + ' ' + mDataList[index].state),
                            ],
                          ),
                        ],
                      ),
                      SizedBox(
                        height: 8.0,
                      ),
                      Row(
                        mainAxisAlignment: MainAxisAlignment.end,
                        mainAxisSize: MainAxisSize.max,
                        children: <Widget>[
                          Chip(
                              backgroundColor: secondaryDark,
                              label: Text('Info number: $n'),
                              ),
                        ],
                      ),
                      SizedBox(height: 6.0),
                    ],
                  ),
                ),
              ),
            ),
          );
        } else {
          return CircularProgressIndicator();
        }
      },
    );
  }
}

答案 1 :(得分:0)

这是我的解决方法

     class _BottomCardsState extends State<BottomCards>{
         bool isLoadingEnded=false;
          Future<Null> getAllData() async{
            await DefaultAssetBundle.of(context).loadString('assets/json/data.json').then((response){
            var decodedData = json.decode(response);
            isLoadingEnded=true;
            setState(() {
              for(Map element in decodedData){
                mDataList.add(Country.fromJson(element));
              }
            });
          })

          }

          @override
          void initState() {
            super.initState();
            getAllData();
          }

          int index = mDataList.first.id;

          @override
          Widget build(BuildContext context) {
            int n = mDataList[index].id;
            return isLoadingEnded ? Container(
              child: Material(
                color: Colors.transparent,
                child: Card(
                  margin: EdgeInsets.symmetric(horizontal: 10.0),
                  elevation: 6.0,
                  child: Container(
                    alignment: Alignment.topCenter,
                    padding: EdgeInsets.symmetric(horizontal: 12.0,),
                    child: Column(
                        Row(
                          mainAxisAlignment: MainAxisAlignment.start,
                          mainAxisSize: MainAxisSize.max,
                          children: <Widget>[
                            Column(                  
                              children: <Widget>[
                                Text(mDataList[index].country + ' ' + mDataList[index].state),
                              ],
                            ),
                          ],
                        ),                  
                        SizedBox(height: 8.0,),
                        Row(
                          mainAxisAlignment: MainAxisAlignment.end,
                          mainAxisSize: MainAxisSize.max,
                          children: <Widget>[
                            Chip(
                              backgroundColor: secondaryDark,
                              label: Text('Info number: $n'),
                            ),
                          ],
                        ),
                        SizedBox(height: 6.0),
                      ],
                    ),
                  ),
                ),
              ),
            ) :  Center(child:new CircularProgressIndicator());
          }
        }