为什么我无法通过 Json 在我的 Flutter 应用程序上获取数据

Why I can't fetch data by Json on my Flutter App

我没有从假 Api 获得任何数据:https://jsonplaceholder.typicode.com/users to my flutter App. Can anyone please give me piece of advise why or how I can get those data on my app. For creating the Model file using https://app.quicktype.io/.

Json模型文件:

import 'dart:convert';

List<JsonModel> jsonModelFromJson(String str) =>
    List<JsonModel>.from(json.decode(str).map((x) => JsonModel.fromJson(x)));

String jsonModelToJson(List<JsonModel> data) =>
    json.encode(List<dynamic>.from(data.map((x) => x.toJson())));

class JsonModel {
  JsonModel({
    this.id,
    this.name,
    this.username,
    this.email,
    this.address,
    this.phone,
    this.website,
    this.company,
  });

  int? id;
  String? name;
  String? username;
  String? email;
  Address? address;
  String? phone;
  String? website;
  Company? company;

  factory JsonModel.fromJson(Map<String, dynamic> json) => JsonModel(
        id: json["id"],
        name: json["name"],
        username: json["username"],
        email: json["email"],
        address: Address.fromJson(json["address"]),
        phone: json["phone"],
        website: json["website"],
        company: Company.fromJson(json["company"]),
      );

  Map<String, dynamic> toJson() => {
        "id": id,
        "name": name,
        "username": username,
        "email": email,
        "address": address?.toJson(),
        "phone": phone,
        "website": website,
        "company": company?.toJson(),
      };
}

class Address {
  Address({
    this.street,
    this.suite,
    this.city,
    this.zipcode,
    this.geo,
  });

  String? street;
  String? suite;
  String? city;
  String? zipcode;
  Geo? geo;

  factory Address.fromJson(Map<String, dynamic> json) => Address(
        street: json["street"],
        suite: json["suite"],
        city: json["city"],
        zipcode: json["zipcode"],
        geo: Geo.fromJson(json["geo"]),
      );

  Map<String, dynamic> toJson() => {
        "street": street,
        "suite": suite,
        "city": city,
        "zipcode": zipcode,
        "geo": geo?.toJson(),
      };
}

class Geo {
  Geo({
    this.lat,
    this.lng,
  });

  String? lat;
  String? lng;

  factory Geo.fromJson(Map<String, dynamic> json) => Geo(
        lat: json["lat"],
        lng: json["lng"],
      );

  Map<String, dynamic> toJson() => {
        "lat": lat,
        "lng": lng,
      };
}

class Company {
  Company({
    this.name,
    this.catchPhrase,
    this.bs,
  });

  String? name;
  String? catchPhrase;
  String? bs;

  factory Company.fromJson(Map<String, dynamic> json) => Company(
        name: json["name"],
        catchPhrase: json["catchPhrase"],
        bs: json["bs"],
      );

  Map<String, dynamic> toJson() => {
        "name": name,
        "catchPhrase": catchPhrase,
        "bs": bs,
      };
}

服务或JsonApi文件:

import 'dart:convert';

import 'package:flutter_learning_from_pageview/Model/JsonModel.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:http/http.dart' as http;

class JsonApi {
  bool loading = true;
  var json_Data;
  Future<JsonModel> getJsonData() async {
    var client = http.Client();
    String uri = "https://jsonplaceholder.typicode.com/users";
    var response = await client.get(Uri.parse(uri));
    var jsonModel = null;
    try {
      if (response.statusCode == 200) {
        var decode = json.decode(response.body);
        jsonModel = JsonModel.fromJson(decode);
        print(jsonModel);
      } else {
        throw Exception("falied to load");
      }
    } catch (Exception) {
      return jsonModel;
    }

    return jsonModel;
  }
}

尝试调用但是进度条没有关闭说明我没有得到数据

import 'dart:convert';


import 'package:flutter/material.dart';
import 'package:flutter_learning_from_pageview/Model/JsonModel.dart';
import 'package:flutter_learning_from_pageview/Service/JsonApi.dart';

class JsonData extends StatefulWidget {
  const JsonData({Key? key}) : super(key: key);

  @override
  _JsonDataState createState() => _JsonDataState();
}

class _JsonDataState extends State<JsonData> {
  bool loading = true;
  Future<JsonModel>? _jsonModel;
  @override
  void initState() {
    _jsonModel = JsonApi().getJsonData();
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return SafeArea(
      child: Scaffold(
        body: FutureBuilder(
          future: _jsonModel,
          builder: (context, snapshot) {
            if (snapshot.hasData) {
              return ListView.builder(
                  //itemCount: json_Data == null ? 0 : json_Data.length,
                  itemBuilder: (context, index) {
                return ListTile(
                  title: Text(""),
                  //subtitle: Text(json_Data[index]["body"]),
                );
              });
            } else {
              return Center(child: CircularProgressIndicator());
            }
          },
        ),
      ),
    );
  }
}

从初始状态你必须这样改变:

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


    void callApi() async {
     _jsonModel = await JsonApi().getJsonData();
    }

因为你没有用 await 调用它,所以它没有数据

我发现了你的问题。您试图在错误的 jsonModel.

中获取数据

删除此代码

       var decode = json.decode(response.body);
       jsonModel = JsonModel.fromJson(decode);

改用这个

       jsonModel = jsonModelFromJson(response.body);

您的 Api 数据采用 Array 格式,您正尝试以 Class 格式存储。

你犯了一些错误所以试着把它改成这样。您正在尝试仅使用一个元素来解析数据列表。

class JsonApi {
  Future<List<JsonModel>> getJsonData() async {
    var client = http.Client();
    String uri = "https://jsonplaceholder.typicode.com/users";
    var response = await client.get(Uri.parse(uri));

    if (response.statusCode == 200) {
      return jsonModelFromJson(response.body);
    } else {
      throw Exception("falied to load");
    }
  }
}

然后试试这个代码

late final Future<List<JsonModel>> _futureData;
  apiCalling() {
    _futureData = JsonApi().getJsonData();
  }

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

  @override
  Widget build(BuildContext context) {
    return SafeArea(
      child: Scaffold(
        body: FutureBuilder(
          future: _futureData,
          builder: (context, AsyncSnapshot<List<JsonModel>> snapshot) {
            if (snapshot.hasData) {
              return ListView.builder(
                  itemCount: snapshot.data!.length,
                  //itemCount: json_Data == null ? 0 : json_Data.length,
                  itemBuilder: (context, index) {
                    return ListTile(
                      onTap: () {
                        setState(() {});
                      },
                      title: Text(snapshot.data![index].name!),
                      //subtitle: Text(json_Data[index]["body"]),
                    );
                  });
            } else {
              return Center(child: CircularProgressIndicator());
            }
          },
        ),
      ),
    );
  }
  1. 确保 response.body 正在返回数据。

  2. 避免使用 ?在 futures 中,否则当 body 为 null 时快照可能一直为空。 ui 将始终显示正在加载。

  3. 为了使您的代码看起来更简单:

内部有状态小部件:

late final Future<List<Data>> _futureData;

并且在您的 initState 中:

@override    
void initState(){
   _futureData = provider.loadFutureData();
   super.initState();
}

或者如果您不使用提供商:

@override    
void initState(){
   _futureData = loadDataFromFunction();
   super.initState();
}

试试下面的代码希望对你有帮助。

Your API Call:

  Future<List<dynamic>> getJobsData() async {
    String url = 'https://jsonplaceholder.typicode.com/users';
    var response = await http.get(Uri.parse(url), headers: {
      'Content-Type': 'application/json',
      'Accept': 'application/json',
    });
    return json.decode(response.body);
  }

Your Widget:

Center(
  child: FutureBuilder<List<dynamic>>(
    future: getJobsData(),
    builder: (context, snapshot) {
      if (snapshot.hasData) {
        return Padding(
          padding: const EdgeInsets.all(8.0),
          child: ListView.builder(
            shrinkWrap: true,
            physics:const NeverScrollableScrollPhysics(),
            itemCount: snapshot.data!.length,
            itemBuilder: (context, index) {
              var id = snapshot.data![index]['id'];
              var name = snapshot.data![index]['name'];
              var username = snapshot.data![index]['username'];
              var email = snapshot.data![index]['email'];
              var phone = snapshot.data![index]['phone'];
              return Card(
                shape: RoundedRectangleBorder(
                  side: BorderSide(
                    color: Colors.green.shade300,
                  ),
                  borderRadius: BorderRadius.circular(15.0),
                ),
                child: ListTile(
                  leading: Text(id.toString()),
                  title: Text(name),
                  subtitle: Text(
                    username + '\n' + email + '\n' + phone.toString(),
                  ),
                ),
              );
            },
          ),
        );
      }
      return const CircularProgressIndicator();
    },
  ),
),

参考我的回答 and 从 json API

获取数据

您的结果屏幕->