在 Flutter 中显示来自 API 的数据

时间:2021-07-27 08:33:41

标签: flutter flutter-layout flutter-listview

我有一个 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 应用程序中的 GestureDetector 小部件中显示这样的数据?

编辑: 以下是回复的一部分:

[{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

1 个答案:

答案 0 :(得分:0)

我认为那是因为

的价值
return Tour.fromJson(jsonDecode(response.body));

与本班要求的类型不同

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