【问题标题】:how to make a text data from json show directly in a page?如何使来自json的文本数据直接显示在页面中?
【发布时间】:2020-03-27 01:20:58
【问题描述】:

我一直试图让来自 json 的数据直接显示在一个页面中,比如一个段落,但我没有这样做,我成功地用一个按钮拉它,但我只想在我进入这个页面后显示数据直接地。 我在这里错过了什么? 非常感谢您的帮助。

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

class Page1 extends StatefulWidget {
  @override
  State<StatefulWidget> createState() {
    // TODO: implement createState
    return Page1State();
  }

  Future<List> getData() async {
    String myURL = 'https://jsonplaceholder.typicode.com/users';
    http.Response response = await http.get(myURL);
    print(getData());
    return json.decode(response.body);
  }
}

class Page1State extends State<Page1> {
  var page = Page1();
  List data;
  List myTextData;


   void getMyData() async {
    data = await (page.getData());
    print(data);
    setState(() {
      myTextData = data;
    });
  }

  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return Scaffold(
      appBar: AppBar(
        title: Text('Page1'),
      ),
      body: Container(
        child: Column(
          children: <Widget>[
            Expanded(
              child: new SingleChildScrollView(
                child: Text(
                  '$getMyData',
                  style: TextStyle(fontSize: 30),
                ),
              ),
            ),
          ],
        ),
      ),
    );
  }
}

import 'package:flutter/material.dart';
import 'Home.dart';

main() async {
  runApp(MaterialApp(
    home: Home(),
    title: '',
  ));
}

【问题讨论】:

  • 因为getMyData是一个void方法,所以你什么都得不到

标签: json android-studio flutter dart


【解决方案1】:

您也可以使用FutureBuilder,这将使您的小部件无状态。 FututeBuilder 的builder 中的快照也有几个有用的字段,例如connectionState,可以让您轻松实现所有状态(等待、完成、错误)。

更多信息在这里:https://api.flutter.dev/flutter/widgets/FutureBuilder-class.html

由于您的输出是 JSON,我还提供了一个如何简单地从中提取数据的示例。

class Page1 extends StatelessWidget {
  Future<List> getData() async {
    String myURL = 'https://jsonplaceholder.typicode.com/users';
    http.Response response = await http.get(myURL);
    return json.decode(response.body);
  }

  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return Scaffold(
      appBar: AppBar(
        title: Text('Page1'),
      ),
      body: Container(
        child: Column(
          children: <Widget>[
            Expanded(
                child: new SingleChildScrollView(
              child: FutureBuilder<List>(
                  future: getData(),
                  builder: (context, snapshot) {
                    if (snapshot.hasData) {
                      return Text(
                        snapshot.data
                            .map((user) => user['name'] as String)
                            .join('\n'),
                        style: TextStyle(fontSize: 30),
                      );
                    } else {
                      return Text('Waiting');
                    }
                  }),
            )),
          ],
        ),
      ),
    );
  }
}

【讨论】:

    【解决方案2】:
    1. 将 getdata 方法保持在您的状态
    2. 当你显示为字符串时不要执行 json.decode

    试试这个

    import 'package:flutter/material.dart';
    import 'dart:async';
    import 'dart:convert';
    import 'package:http/http.dart' as http;
    
    class Page1 extends StatefulWidget {
      @override
      State<StatefulWidget> createState() {
        // TODO: implement createState
            return Page1State();
          }
        }
     @override
      void initState() { 
        super.initState();
        getMyData();
      }
    
    class Page1State extends State<Page1> {
      String data;   
    
      void getMyData() async {
        String myURL = 'https://jsonplaceholder.typicode.com/users';
        http.Response response = await http.get(myURL);
        setState((){
          data = response.body; //do not decode as you want to show as  string
        });
      }
    
      @override
      Widget build(BuildContext context) {
        // TODO: implement build
        return Scaffold(
          appBar: AppBar(
            title: Text('Page1'),
          ),
          body: Container(
            child: Column(
              children: <Widget>[
                Expanded(
                  child: new SingleChildScrollView(
                    child: data == null ? CircularProgressIndicator() : Text(
                      '$data',
                      style: TextStyle(fontSize: 30),
                    ),
                  ),
                ),
              ],
            ),
          ),
        );
      }
    }
    

    【讨论】:

    • 这种情况下 CircularProgressIndicator 一直循环,并且没有使用异步库,这正常吗?
    • 对不起,异步不再需要,我忘记了 getmydata,我们应该在 initstate 中这样做,已经进行了修改。请检查
    【解决方案3】:

    试试,

    List<MyModel> mList=List();
    

    然后从 api 响应中更新 myTextData,

     void getMyData() async {
        data = await (page.getData());
        print(data);
        setState(() {
          mList.addAll(data);
        });
      }
    
    
    ListView.builder
      (
        itemCount: mList.length,
        itemBuilder: (BuildContext ctxt, int index) {
         return new Text(mList[index]);
        }
      )
    

    【讨论】:

    • 它给了我null,这是我首先遇到的问题。
    • 我不得不保留 List myTextData 而不是 String。
    • 它给了我 NoSuchMethodError: The getter 'length' was called on null.
    • 检查我更新的答案!我忘了初始化 List();
    猜你喜欢
    • 2017-02-06
    • 1970-01-01
    • 2023-03-24
    • 2019-12-28
    • 2020-12-13
    • 1970-01-01
    • 2018-03-21
    • 2017-11-03
    • 1970-01-01
    相关资源
    最近更新 更多