在 Flutter 中显示来自 API 的数据

Posted

技术标签:

【中文标题】在 Flutter 中显示来自 API 的数据【英文标题】:Display Data from API in Flutter 【发布时间】:2021-10-03 01:55:24 【问题描述】:

我有一个 Swagger API,我需要显示其中的数据。

我尝试了以下代码:

touren.dart

import 'dart:convert';

import 'package:flutter/material.dart';
import 'package:lieferantenapp/components/myTwoLineText.dart';
import 'package:lieferantenapp/entities/tour.dart';
import 'package:lieferantenapp/variables.dart' as variables;
import 'package:http/http.dart' as http;

class Touren extends StatefulWidget 
  @override
  _TourenState createState() => _TourenState();


class _TourenState extends State<Touren> 
  Future<Tour> futureTour;

  @override
  void initState() 
    super.initState();
    futureTour = fetchTour();
  

  //--- API URL
  final dynamic url = "---";

  //Ausgewähltes Datum - Standard Heute
  String _selectedDate = '2021-01-22';
  //'$DateTime.now().year-$DateTime.now().month-$DateTime.now().day';

  //Touren aus DB
  Future<Tour> fetchTour() async 
    //DB User
    String username = '---';
    //DB PW
    String password = '---';
    //DB Auth
    String basicAuth =
        'Basic ' + base64Encode(utf8.encode('$username:$password'));

    //http request
    final response = await http.get(
        Uri.parse(url +
            '---'),
        headers: 'authorization': basicAuth);
    print(
        url + '---');

    if (response.statusCode == 200) 
      // If the server did return a 200 OK response,
      // then parse the JSON.
      return Tour.fromJson(jsonDecode(response.body));
     else 
      // If the server did not return a 200 OK response,
      // then throw an exception.
      throw Exception('Failed to load Tour: $response.statusCode');
    
  

  //DatePicker
  Future<DateTime> _showPicker(BuildContext context) 
    return showDatePicker(
      context: context,
      initialDate: DateTime.now(),
      firstDate: DateTime(1990),
      lastDate: DateTime(2100),
      //SelectedDate wird gespeichert für DB gespeichert
    ).then((pickedDate) 
      _selectedDate =
          '$pickedDate.year-$pickedDate.month-$pickedDate.day';
      print(_selectedDate);
      setState(() 
        fetchTour();
      );
      return null;
    );
  

  @override
  Widget build(BuildContext context) 
    return Scaffold(
      floatingActionButton: FloatingActionButton(
        child: Icon(
          Icons.today,
        ),
        onPressed: () 
          _showPicker(context);
        ,
      ),
      appBar: AppBar(
        backgroundColor: Colors.transparent,
        shadowColor: Colors.transparent,
        iconTheme: IconThemeData(color: Colors.black),
        title: Text(
          "Touren",
          style: TextStyle(color: Colors.black),
        ),
      ),
      body: SingleChildScrollView(
        child: Padding(
          padding: const EdgeInsets.all(20),
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              Text(
                "Tour auswählen: ",
                style: Theme.of(context)
                    .textTheme
                    .subtitle1
                    .apply(color: variables.red, fontWeightDelta: 1),
              ),
              FutureBuilder<Tour>(
                future: futureTour,
                builder: (context, snapshot) 
                  print("Snapshot: $snapshot");
                  if (snapshot.hasData) 
                    return GestureDetector(
                      onTap: () 
                        Navigator.pop(context);
                      ,
                      child: MyTwoLineText(
                          snapshot.data.tourId, snapshot.data.kundenAnzahl),
                    );
                   else if (snapshot.hasError) 
                    return Text("$snapshot.error");
                  

                  // By default, show a loading spinner.
                  return CircularProgressIndicator();
                ,
              ),
              SizedBox(height: 20),
              //TODO implement onTap Tour
              GestureDetector(
                onTap: () 
                  Navigator.pop(context);
                ,
                child: MyTwoLineText(0100, 37),
              ),
              GestureDetector(
                onTap: () 
                  Navigator.pop(context);
                ,
                child: MyTwoLineText(0100, 37),
              ),
              GestureDetector(
                onTap: () 
                  Navigator.pop(context);
                ,
                child: MyTwoLineText(0100, 37),
              ),
              GestureDetector(
                onTap: () 
                  Navigator.pop(context);
                ,
                child: MyTwoLineText(0100, 37),
              ),
              GestureDetector(
                onTap: () 
                  Navigator.pop(context);
                ,
                child: MyTwoLineText(0100, 37),
              ),
              GestureDetector(
                onTap: () 
                  Navigator.pop(context);
                ,
                child: MyTwoLineText(0100, 37),
              ),
              GestureDetector(
                onTap: () 
                  Navigator.pop(context);
                ,
                child: MyTwoLineText(0100, 37),
              ),
            ],
          ),
        ),
      ),
    );
  

tour.dart

class Tour 
  final String lieferdatum;
  final int tourId;
  final String tourBezeichnung;
  final int kundenAnzahl;
  final int menge;
  final int mandantId;
  final String mandant;
  final bool showOnMobile;
  final int fahrerId1;
  final int fahrerId2;
  final int fahrerId3;
  final String fahrer1;
  final String fahrer2;
  final String fahrer3;

  Tour(
    this.lieferdatum,
    this.tourId,
    this.tourBezeichnung,
    this.kundenAnzahl,
    this.menge,
    this.mandantId,
    this.mandant,
    this.showOnMobile,
    this.fahrerId1,
    this.fahrerId2,
    this.fahrerId3,
    this.fahrer1,
    this.fahrer2,
    this.fahrer3,
  );

  /*factory Tour.fromJson(List<dynamic> json) 
    print("---------------------------------------" + json[0]['lieferdatum']);
    return Tour(
      lieferdatum: json[0],
      tourId: json[1],
      tourBezeichnung: json[2],
      kundenAnzahl: json[3],
      menge: json[4],
      mandantId: json[5],
      mandant: json[6],
      showOnMobile: json[7],
      fahrerId1: json[8],
      fahrerId2: json[9],
      fahrerId3: json[10],
      fahrer1: json[11],
      fahrer2: json[12],
      fahrer3: json[13],
    );
    */
  factory Tour.fromJson(Map<String, dynamic> json) 
    print(json);
    return Tour(
      lieferdatum: json[0]['lieferdatum'],
      tourId: json[0]['tourId'],
      tourBezeichnung: json[0]['tourBezeichnung'],
      kundenAnzahl: json[0]['kundenAnzahl'],
      menge: json[0]['menge'],
      mandantId: json[0]['mandantId'],
      mandant: json[0]['mandant'],
      showOnMobile: json[0]['showOnMobile'],
      fahrerId1: json[0]['fahrerId1'],
      fahrerId2: json[0]['fahrerId2'],
      fahrerId3: json[0]['fahrerId3'],
      fahrer1: json[0]['fahrer1'],
      fahrer2: json[0]['fahrer2'],
      fahrer3: json[0]['fahrer3'],
    );
  

应显示数据的字段内部出现以下错误:

type 'List<dynamic>' is not a subtype of type 'Map<String, dynamic>'

由于我客户的数据隐私,我不得不删除链接、用户和密码……。

我该如何解决这个问题,并在我的 Flutter App 中的 GestureDetector Widget 中显示这样的数据?

编辑: 以下是部分回复:

[lieferdatum: 2021-01-22T00:00:00, tourId: 1, tourBezeichnung: Tour 1, kundenAnzahl: 9, menge: 9, mandantId: 0, mandant: null, showOnMobile: true, fahrerId1: 3, fahrerId2: 0, fahrerId3: 0, fahrer1: Michael Kupka, fahrer2: n/a, fahrer3: n/a, lieferdatum: 2021-01-22T00:00:00, tourId: 2, tourBezeichnung: Tour 2, kundenAnzahl: 7, menge: 7, mandantId: 0, mandant: null, showOnMobile: true, fahrerId1: 3, fahrerId2: 0, fahrerId3: 0, fahrer1: Michael Kupka, fahrer2: n/a, fahrer3: n/a, lieferdatum: 2021-01-22T00:00:00, tourId: 3, tourBezeichnung: Tour 3, kundenAnzahl: 4, menge: 4, mandantId: 0, mandant: null, showOnMobile: false, fahrerId1: 4, fahrerId2: 3, fahrerId3: 0, fahrer1: thias-systeme, fahrer2: Max Muster, fahrer3: n/a, lieferdatum: 2021-01-22T00:00:00, tourId: 5, tourBezeichnung: Tour TK, kundenAnzahl: 2, menge: 2, mandantId: 0, mandant: null, showOnMobile: false, fahrerId1: 1, fahrerId2: 2, fahrerId3: 0, fahrer1: Max Muster, fahrer2: n/a, fahrer3: n/a, lieferdatum: 2021-01-22T00:00:00

【问题讨论】:

你应该在这里参考我的答案***.com/a/68533647/13997210 你的API返回的是什么json结构?如果可能,请发布您的API response!! 这是我的 API 回复 userId: 1, id: 1, title: "quidem molestiae enim" 【参考方案1】:

我认为那是因为价值

return Tour.fromJson(jsonDecode(response.body));

与本课程要求的类型不同

MyTwoLineText(
  snapshot.data.tourId, snapshot.data.kundenAnzahl),
)

【讨论】:

以上是关于在 Flutter 中显示来自 API 的数据的主要内容,如果未能解决你的问题,请参考以下文章

来自 api 的信息不显示 - Flutter

Flutter 如何将裁剪器添加到 fl_chart (CustomPainter)

Flutter:延迟加载来自 Firestore 的数据

Flutter图表库fl_chart的使用解析(二)-折线图

如何在 Flutter 中使用 Provider 正确获取 API

flutter - 来自 REST API 的实时流数据