如何在 Flutter 中使用 JSON 数据的变量(不是列表视图)

How can I use a Variable of JSON data in Flutter (not a listview)

我是在查看了很多示例和类似问题后提出的,但我无法理解。 我只想从 json 映射中的 id 获取某些数据到 Flutter 中。 我通过 php 收到的是 JSON 的 2 个字符串(这是正确的 JSON 我已经用 jsonlint 检查过):

[{"id":1,"firstname":"John","surname":"Wick","guitarbrand":"Ibanez","votes":15,"pickups":2},{"id":2,"firstname":"Elvis","surname":"Presley","guitarbrand":"LesPaul","votes":10,"pickups":1},{"id":3,"firstname":"Kirk","surname":"Hammet","guitarbrand":"HarleyBenton","votes":9,"pickups":3}]


{"id":1,"firstname":"John","surname":"Wick","guitarbrand":"Ibanez","votes":15,"pickups":2}

我正在使用一个单独的 Dart 文件,我将其导入 main.dart:

    import 'dart:convert';

import 'package:http/http.dart' as http;

Future<Dayplay> fetchDayplay() async {
  final resp1 = await http.get(Uri.parse('http://somewhere.com/getdayentries.php'));
  if (resp1.statusCode == 200) {
    // If the server did return a 200 OK response,
    // then parse the JSON.
    print('Response body: ${json.decode((resp1.body))}');
    return Dayplay.fromJson(jsonDecode(resp1.body));
  } else {
    // If the server did not return a 200 OK response,
    // then throw an exception.
    throw Exception('Failed to load album');
  }
}


Future<Winner> fetchWinner() async {
  final resp2 = await http.get(Uri.parse('http://somewhere.com/getwinner.php'));
  if (resp2.statusCode == 200) {
    // If the server did return a 200 OK response,
    // then parse the JSON.
    print('Response body: ${json.decode((resp2.body))}');
    return Winner.fromJson(jsonDecode(resp2.body));
  } else {
    // If the server did not return a 200 OK response,
    // then throw an exception.
    throw Exception('Failed to load album');
  }
}

class Dayplay {
  int? _id;
  String? _firstname;
  String? _surname;
  String? _guitarbrand;
  int? _votes;
  int? _pickups;

  Dayplay(
      {int? id,
        String? firstname,
        String? surname,
        String? guitarbrand,
        int? votes,
        int? pickups}) {
    if (id != null) {
      this._id = id;
    }
    if (firstname != null) {
      this._firstname = firstname;
    }
    if (surname != null) {
      this._surname = surname;
    }
    if (guitarbrand != null) {
      this._guitarbrand = guitarbrand;
    }
    if (votes != null) {
      this._votes = votes;
    }
    if (pickups != null) {
      this._pickups = pickups;
    }
  }

  int? get id => _id;
  set id(int? id) => _id = id;
  String? get firstname => _firstname;
  set firstname(String? firstname) => _firstname = firstname;
  String? get surname => _surname;
  set surname(String? surname) => _surname = surname;
  String? get guitarbrand => _guitarbrand;
  set guitarbrand(String? guitarbrand) => _guitarbrand = guitarbrand;
  int? get votes => _votes;
  set votes(int? votes) => _votes = votes;
  int? get pickups => _pickups;
  set pickups(int? pickups) => _pickups = pickups;

  Dayplay.fromJson(Map<String, dynamic> json) {
    _id = json['id'];
    _firstname = json['firstname'];
    _surname = json['surname'];
    _guitarbrand = json['guitarbrand'];
    _votes = json['votes'];
    _pickups = json['pickups'];
  }

  Map<String, dynamic> toJson() {
    final Map<String, dynamic> data = new Map<String, dynamic>();
    data['id'] = this._id;
    data['firstname'] = this._firstname;
    data['surname'] = this._surname;
    data['guitarbrand'] = this._guitarbrand;
    data['votes'] = this._votes;
    data['pickups'] = this._pickups;
    return data;
  }
}

class Winner {
  int? _id;
  String? _firstname;
  String? _surname;
  String? _guitarbrand;
  int? _votes;
  int? _pickups;

  Winner(
      {int? id,
        String? firstname,
        String? surname,
        String? guitarbrand,
        int? votes,
        int? pickups}) {
    if (id != null) {
      this._id = id;
    }
    if (firstname != null) {
      this._firstname = firstname;
    }
    if (surname != null) {
      this._surname = surname;
    }
    if (guitarbrand != null) {
      this._guitarbrand = guitarbrand;
    }
    if (votes != null) {
      this._votes = votes;
    }
    if (pickups != null) {
      this._pickups = pickups;
    }
  }

  int? get id => _id;
  set id(int? id) => _id = id;
  String? get firstname => _firstname;
  set firstname(String? firstname) => _firstname = firstname;
  String? get surname => _surname;
  set surname(String? surname) => _surname = surname;
  String? get guitarbrand => _guitarbrand;
  set guitarbrand(String? guitarbrand) => _guitarbrand = guitarbrand;
  int? get votes => _votes;
  set votes(int? votes) => _votes = votes;
  int? get pickups => _pickups;
  set pickups(int? pickups) => _pickups = pickups;

  Winner.fromJson(Map<String, dynamic> json) {
    _id = json['id'];
    _firstname = json['firstname'];
    _surname = json['surname'];
    _guitarbrand = json['guitarbrand'];
    _votes = json['votes'];
    _pickups = json['pickups'];
  }

  Map<String, dynamic> toJson() {
    final Map<String, dynamic> data = new Map<String, dynamic>();
    data['id'] = this._id;
    data['firstname'] = this._firstname;
    data['surname'] = this._surname;
    data['guitarbrand'] = this._guitarbrand;
    data['votes'] = this._votes;
    data['pickups'] = this._pickups;
    return data;
  }
}

这部分是 Main.dart 我需要数据的地方:

    import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'package:fiveupmusic/getdata.dart';

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

  @override
  State<Home> createState() => _HomeState();
}

class _HomeState extends State<Home> {
  var idctl = "";
  late bool error, sending, success;
  late Future<Dayplay> futureDayplay;
  late Future<Winner> futureWinner; 
  
  @override
  void initState() {
    futureDayplay = fetchDayplay();
    futureWinner = fetchWinner();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.black,
      body: FutureBuilder(
        future: futureDayplay,
        builder: (BuildContext context, AsyncSnapshot snapshot) {
         if (snapshot.hasData) {
            return Text(snapshot.data!.bandname);
          } else if (snapshot.hasError) {
            return Text('${snapshot.error}');
          }
          print("snapshot");
          print(snapshot.data);
          return SafeArea(
                child: SingleChildScrollView(
                  child: Column(
                    crossAxisAlignment: CrossAxisAlignment.center,
                    children: <Widget>[
                      Image.asset('assets/images/top_logo_320x40.jpg'),
                      Center(child: Text('Result: (how do I get the variable data here?)',
                        style: TextStyle(
                          color: Colors.lightBlue[100],
                        ),
                      )),..............

-我可以在同一个 FutureBuilder 中使用 2 个 Futures 吗?我需要来自两个 JSON 字符串

的数据

-如何获取某个id的数据?

我通过打印命令看到了数据,我得到了这个:

E/flutter (27453): [ERROR:flutter/lib/ui/ui_dart_state.cc(209)] Unhandled Exception: type 'List<dynamic>' is not a subtype of type 'Map<String, dynamic>'

E/flutter (27130):  <asynchronous suspension>

我不明白为什么在第一个 JSON 数据之后出现错误 在第二个接收到的字符串之后没有错误。 我在 Android Studio 中没有任何其他错误。

感谢您提供有关如何解决此问题的更多见解。

一种方法是使用 Future.wait 等待两个调用。 data 就是结果列表。使用 firstWhere 从列表中查找对象。

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        body: Center(
          child: FutureBuilder(
            future: Future.wait([fetchPosts(), fetchUser()]),
            builder: (context, snapshot) {
              if (snapshot.hasError) {
                return Text('${snapshot.error}');
              } else if (snapshot.hasData) {
                final posts = (snapshot.data as List)[0] as List<dynamic>;
                final user = (snapshot.data as List)[1];
                final userId = user['id'];
                final post = posts.firstWhere((post) => post['userId'] == userId);
                return Text('$post');
              } else {
                return const Text('Loading ...');
              }
            }
          )
        ),
      ),
    );
  }
  
  Future<List<dynamic>> fetchPosts() async {
    final resp1 = await http.get(Uri.parse('https://jsonplaceholder.typicode.com/posts'));
    if (resp1.statusCode == 200) {
      return json.decode((resp1.body));
    } else {
      throw Exception('Failed to load');
    }
  }

  Future<Map<String,dynamic>> fetchUser() async {
    final resp2 = await http.get(Uri.parse('https://jsonplaceholder.typicode.com/users/1'));
    if (resp2.statusCode == 200) {
      return json.decode((resp2.body));
    } else {
      throw Exception('Failed to load');
    }
  }
}