Flutter 解析 Google 书籍 API

Flutter parsing Google Books API

我正在尝试在新的 flutter 应用程序中使用 google 书籍 API,但在将 json 解析为可用格式时遇到了很多问题。我是编码和颤动的新手,并使用以下文章尝试学习如何解析 json:https://medium.com/flutter-community/parsing-complex-json-in-flutter-747c46655f51

我的代码可能完全不正确,但如果能帮我解决这个问题,我将不胜感激。 objective 是为了获取书籍列表,我可以在其中为每本书制作一张卡片,其中包含书籍的详细信息。我对 UI 的创建很好,这只是我正在努力的 json。

我的 类 代码将 json 应用于:

class Volume {
  List<VolumeInfo> topLevelRelated;

  Volume({this.topLevelRelated});

  factory Volume.fromJson(Map<String, dynamic> parsedJson) {
    var list = parsedJson['items'] as List;
    List<VolumeInfo> volumeList =
        list.map((i) => VolumeInfo.fromJson(i)).toList();
    return Volume(topLevelRelated: volumeList);
  }
}

class VolumeInfo {
  RelatedBook relatedTitles;

  VolumeInfo({this.relatedTitles});

  factory VolumeInfo.fromJson(Map<String, dynamic> parsedJson) {
    return VolumeInfo(
        relatedTitles: RelatedBook.fromJson(parsedJson['volumeinfo']));
  }
}

class RelatedBook {
  String title;
  List<String> authors;
  ImageLinks imagelink;
  List<IndustryIds> iSBN13;
  String printType;

  RelatedBook(
      {this.authors, this.imagelink, this.iSBN13, this.printType, this.title});

  factory RelatedBook.fromJson(Map<String, dynamic> parsedJson) {
    //this is to get ISBNs for related books
    var list = parsedJson['industryIdentifiers'] as List;
    List<IndustryIds> idList =
        list.map((i) => IndustryIds.fromJson(i)).toList();
    //end of ISBN list code

    //authors to a list code
    var authorsFromJson = parsedJson['authors'];
    List<String> authorsList = new List<String>.from(authorsFromJson);
    //end of authors code

    return RelatedBook(
        iSBN13: idList,
        title: parsedJson['title'],
        authors: authorsList,
        printType: parsedJson['printType'],
        imagelink: ImageLinks.fromJson(parsedJson['imageLinks']));
  }
}

class ImageLinks {
  String smallthumb;
  String bigthumb;

  ImageLinks({this.bigthumb, this.smallthumb});

  factory ImageLinks.fromJson(Map<String, String> parsedJson) {
    return ImageLinks(
        bigthumb: parsedJson['thumbnail'],
        smallthumb: parsedJson['smallThumbnail']);
  }
}

class IndustryIds {
  String identifier;
  String type;

  IndustryIds({this.type, this.identifier});

  factory IndustryIds.fromJson(Map<String, dynamic> parsedJson) {
    return IndustryIds(
        type: parsedJson['type'], identifier: parsedJson['identifier']);
  }
}

class Authors {
  List<String> author;

  Authors({this.author});

  factory Authors.fromJson(Map<String, dynamic> parsedJson) {
    return Authors(author: parsedJson['authors']);
  }
}

和我的 api 调用代码并将其转换为可用对象:

Future<List<Volume>> getRelateds() async {

    final jsonResponse = await http.get(
        'https://www.googleapis.com/books/v1/volumes?q=${isbn}&maxResults=3');

    Volume otherBook1 = Volume.fromJson(json.decode(jsonResponse.body));

    print(otherBook1);
    return Volume;
  }

为糟糕的代码道歉,非常感谢任何帮助。

示例 json 响应:

{
    "kind": "books#volumes",
    "totalItems": 644,
    "items": [
        {
            "kind": "books#volume",
            "id": "zEzVjgEACAAJ",
            "etag": "Rgo2+5tbv7o",
            "selfLink": "https://www.googleapis.com/books/v1/volumes/zEzVjgEACAAJ",
            "volumeInfo": {
                "title": "Austral",
                "authors": [
                    "Paul McAuley"
                ],
                "publisher": "Gollancz",
                "publishedDate": "2018-10-09",
                "description": "The great geoengineering projects have failed. The world is still warming, sea levels are still rising, and the Antarctic Peninsula is home to Earth's newest nation, with life quickened by ecopoets spreading across valleys and fjords exposed by the retreat of the ice. Austral Morales Ferrado, a child of the last generation of ecopoets, is a husky: an edited person adapted to the unforgiving climate of the far south, feared and despised by most of its population. She's been a convict, a corrections officer in a labour camp, and consort to a criminal, and now, out of desperation, she has committed the kidnapping of the century. But before she can collect the ransom and make a new life elsewhere, she must find a place of safety amongst the peninsula's forests and icy plateaus, and evade a criminal gang that has its own plans for the teenage girl she's taken hostage. Blending the story of Austral's flight with the fractured history of her family and its role in the colonisation of Antarctica, Austral is a vivid portrayal of a treacherous new world created by climate change, and shaped by the betrayals and mistakes of the past. 'Paul McAuley's balanced grasp of science and literature, always a rare attribute in the writer of prose fiction, is combined with the equally rare ability to look at today's problems and know which are really problems, and what can be done about them.' William Gibson",
                "industryIdentifiers": [
                    {
                        "type": "ISBN_10",
                        "identifier": "1473217326"
                    },
                    {
                        "type": "ISBN_13",
                        "identifier": "9781473217324"
                    }
                ],
                "readingModes": {
                    "text": false,
                    "image": false
                },
                "pageCount": 288,
                "printType": "BOOK",
                "categories": [
                    "Fiction"
                ],
                "averageRating": 3,
                "ratingsCount": 1,
                "maturityRating": "NOT_MATURE",
                "allowAnonLogging": false,
                "contentVersion": "preview-1.0.0",
                "panelizationSummary": {
                    "containsEpubBubbles": false,
                    "containsImageBubbles": false
                },
                "imageLinks": {
                    "smallThumbnail": "http://books.google.com/books/content?id=zEzVjgEACAAJ&printsec=frontcover&img=1&zoom=5&source=gbs_api",
                    "thumbnail": "http://books.google.com/books/content?id=zEzVjgEACAAJ&printsec=frontcover&img=1&zoom=1&source=gbs_api"
                },
                "language": "en",
                "previewLink": "http://books.google.co.uk/books?id=zEzVjgEACAAJ&dq=9781473217324&hl=&cd=1&source=gbs_api",
                "infoLink": "http://books.google.co.uk/books?id=zEzVjgEACAAJ&dq=9781473217324&hl=&source=gbs_api",
                "canonicalVolumeLink": "https://books.google.com/books/about/Austral.html?hl=&id=zEzVjgEACAAJ"
            },
            "saleInfo": {
                "country": "GB",
                "saleability": "NOT_FOR_SALE",
                "isEbook": false
            },
            "accessInfo": {
                "country": "GB",
                "viewability": "NO_PAGES",
                "embeddable": false,
                "publicDomain": false,
                "textToSpeechPermission": "ALLOWED",
                "epub": {
                    "isAvailable": false
                },
                "pdf": {
                    "isAvailable": false
                },
                "webReaderLink": "http://play.google.com/books/reader?id=zEzVjgEACAAJ&hl=&printsec=frontcover&source=gbs_api",
                "accessViewStatus": "NONE",
                "quoteSharingAllowed": false
            },
            "searchInfo": {
                "textSnippet": "Blending the story of Austral&#39;s flight with the fractured history of her family and its role in the colonisation of Antarctica, Austral is a vivid portrayal of a treacherous new world created by climate change, and shaped by the betrayals ..."
            }
        },
        {
            "kind": "books#volume",
            "id": "biKbAAAACAAJ",
            "etag": "2OgHBM7bBgk",
            "selfLink": "https://www.googleapis.com/books/v1/volumes/biKbAAAACAAJ",
            "volumeInfo": {
                "title": "Four Hundred Billion Stars",
                "authors": [
                    "Paul J. McAuley"
                ],
                "publisher": "Del Rey Books",
                "publishedDate": "1988",
                "description": "Dorothy Yoshida, an astronomer and telepath, joins the archaelogical team exploring the mysterious ruins of a nearly dead planet that shows some signs of returning to life",
                "industryIdentifiers": [
                    {
                        "type": "ISBN_10",
                        "identifier": "0345351754"
                    },
                    {
                        "type": "ISBN_13",
                        "identifier": "9780345351753"
                    }
                ],
                "readingModes": {
                    "text": false,
                    "image": false
                },
                "pageCount": 282,
                "printType": "BOOK",
                "categories": [
                    "Fiction"
                ],
                "maturityRating": "NOT_MATURE",
                "allowAnonLogging": false,
                "contentVersion": "preview-1.0.0",
                "language": "en",
                "previewLink": "http://books.google.co.uk/books?id=biKbAAAACAAJ&dq=9781473217324&hl=&cd=2&source=gbs_api",
                "infoLink": "http://books.google.co.uk/books?id=biKbAAAACAAJ&dq=9781473217324&hl=&source=gbs_api",
                "canonicalVolumeLink": "https://books.google.com/books/about/Four_Hundred_Billion_Stars.html?hl=&id=biKbAAAACAAJ"
            },
            "saleInfo": {
                "country": "GB",
                "saleability": "NOT_FOR_SALE",
                "isEbook": false
            },
            "accessInfo": {
                "country": "GB",
                "viewability": "NO_PAGES",
                "embeddable": false,
                "publicDomain": false,
                "textToSpeechPermission": "ALLOWED",
                "epub": {
                    "isAvailable": false
                },
                "pdf": {
                    "isAvailable": false
                },
                "webReaderLink": "http://play.google.com/books/reader?id=biKbAAAACAAJ&hl=&printsec=frontcover&source=gbs_api",
                "accessViewStatus": "NONE",
                "quoteSharingAllowed": false
            },
            "searchInfo": {
                "textSnippet": "Dorothy Yoshida, an astronomer and telepath, joins the archaelogical team exploring the mysterious ruins of a nearly dead planet that shows some signs of returning to life"
            }
        },
        {
            "kind": "books#volume",
            "id": "Z7x9BAAAQBAJ",
            "etag": "Qy9xvTfprmo",
            "selfLink": "https://www.googleapis.com/books/v1/volumes/Z7x9BAAAQBAJ",
            "volumeInfo": {
                "title": "Something Coming Through",
                "authors": [
                    "Paul McAuley"
                ],
                "publisher": "Hachette UK",
                "publishedDate": "2015-02-19",
                "description": "The aliens are here. And they want to help. The extraordinary new project from one of the country's most acclaimed and consistently brilliant SF novelists of the last 30 years. The Jackaroo have given humanity fifteen worlds and the means to reach them. They're a chance to start over, but they're also littered with ruins and artifacts left by the Jackaroo's previous clients. Miracles that could reverse the damage caused by war, climate change, and rising sea levels. Nightmares that could forever alter humanity - or even destroy it. Chloe Millar works in London, mapping changes caused by imported scraps of alien technology. When she stumbles across a pair of orphaned kids possessed by an ancient ghost, she must decide whether to help them or to hand them over to the authorities. Authorities who believe that their visions point towards a new kind of danger. And on one of the Jackaroo's gift-worlds, the murder of a man who has just arrived from Earth leads policeman Vic Gayle to a war between rival gangs over possession of a remote excavation site. Something is coming through. Something linked to the visions of Chloe's orphans, and Vic Gayle's murder investigation. Something that will challenge the limits of the Jackaroo's benevolence ...",
                "industryIdentifiers": [
                    {
                        "type": "ISBN_13",
                        "identifier": "9781473203969"
                    },
                    {
                        "type": "ISBN_10",
                        "identifier": "1473203961"
                    }
                ],
                "readingModes": {
                    "text": true,
                    "image": false
                },
                "pageCount": 320,
                "printType": "BOOK",
                "categories": [
                    "Fiction"
                ],
                "averageRating": 3.5,
                "ratingsCount": 2,
                "maturityRating": "NOT_MATURE",
                "allowAnonLogging": true,
                "contentVersion": "1.8.7.0.preview.2",
                "panelizationSummary": {
                    "containsEpubBubbles": false,
                    "containsImageBubbles": false
                },
                "imageLinks": {
                    "smallThumbnail": "http://books.google.com/books/content?id=Z7x9BAAAQBAJ&printsec=frontcover&img=1&zoom=5&edge=curl&source=gbs_api",
                    "thumbnail": "http://books.google.com/books/content?id=Z7x9BAAAQBAJ&printsec=frontcover&img=1&zoom=1&edge=curl&source=gbs_api"
                },
                "language": "en",
                "previewLink": "http://books.google.co.uk/books?id=Z7x9BAAAQBAJ&printsec=frontcover&dq=9781473217324&hl=&cd=3&source=gbs_api",
                "infoLink": "https://play.google.com/store/books/details?id=Z7x9BAAAQBAJ&source=gbs_api",
                "canonicalVolumeLink": "https://market.android.com/details?id=book-Z7x9BAAAQBAJ"
            },
            "saleInfo": {
                "country": "GB",
                "saleability": "FOR_SALE",
                "isEbook": true,
                "listPrice": {
                    "amount": 3.99,
                    "currencyCode": "GBP"
                },
                "retailPrice": {
                    "amount": 3.99,
                    "currencyCode": "GBP"
                },
                "buyLink": "https://play.google.com/store/books/details?id=Z7x9BAAAQBAJ&rdid=book-Z7x9BAAAQBAJ&rdot=1&source=gbs_api",
                "offers": [
                    {
                        "finskyOfferType": 1,
                        "listPrice": {
                            "amountInMicros": 3990000,
                            "currencyCode": "GBP"
                        },
                        "retailPrice": {
                            "amountInMicros": 3990000,
                            "currencyCode": "GBP"
                        },
                        "giftable": true
                    }
                ]
            },
            "accessInfo": {
                "country": "GB",
                "viewability": "PARTIAL",
                "embeddable": true,
                "publicDomain": false,
                "textToSpeechPermission": "ALLOWED_FOR_ACCESSIBILITY",
                "epub": {
                    "isAvailable": true,
                    "acsTokenLink": "http://books.google.co.uk/books/download/Something_Coming_Through-sample-epub.acsm?id=Z7x9BAAAQBAJ&format=epub&output=acs4_fulfillment_token&dl_type=sample&source=gbs_api"
                },
                "pdf": {
                    "isAvailable": false
                },
                "webReaderLink": "http://play.google.com/books/reader?id=Z7x9BAAAQBAJ&hl=&printsec=frontcover&source=gbs_api",
                "accessViewStatus": "SAMPLE",
                "quoteSharingAllowed": false
            },
            "searchInfo": {
                "textSnippet": "And on one of the Jackaroo&#39;s gift-worlds, the murder of a man who has just arrived from Earth leads policeman Vic Gayle to a war between rival gangs over possession of a remote excavation site. Something is coming through."
            }
        }
    ]
}

我已经用下面的代码解决了这个问题:

class VolumeJson {
  final int totalItems;

  final String kind;

  final List<Item> items;

  VolumeJson({this.items, this.kind, this.totalItems});

  factory VolumeJson.fromJson(Map<String, dynamic> parsedJson) {
    var list = parsedJson['items'] as List;

    List<Item> itemList = list.map((i) => Item.fromJson(i)).toList();
    print(itemList.length);

    return VolumeJson(
        items: itemList,
        kind: parsedJson['kind'],
        totalItems: parsedJson['totalItems']);
  }
}

class Item {
  final String kind;

  final String etag;

  final VolumeInfo volumeinfo;

  Item({this.kind, this.etag, this.volumeinfo});

  factory Item.fromJson(Map<String, dynamic> parsedJson) {
    return Item(
        kind: parsedJson['kind'],
        etag: parsedJson['etag'],
        volumeinfo: VolumeInfo.fromJson(parsedJson['volumeInfo']));
  }
}

class VolumeInfo {
  final String title;

  final String publisher;

  final String printType;

  final ImageLinks image;



  VolumeInfo(
      {this.printType, this.title, this.publisher, this.image, });

  factory VolumeInfo.fromJson(Map<String, dynamic> parsedJson) {

    print('GETTING DATA');
    //print(isbnList[1]);
    return VolumeInfo(
      title: parsedJson['title'],
      publisher: parsedJson['publisher'],
      printType: parsedJson['printType'],
      image: ImageLinks.fromJson(
        parsedJson['imageLinks'],
      ),

    );
  }
}

class ImageLinks {
  final String thumb;

  ImageLinks({this.thumb});

  factory ImageLinks.fromJson(Map<String, dynamic> parsedJson) {
    return ImageLinks(thumb: parsedJson['thumbnail']);
  }
}

class ISBN {
  final String iSBN13;
  final String type;

  ISBN({this.iSBN13, this.type});

  factory ISBN.fromJson(Map<String, dynamic> parsedJson) {
    return ISBN(
      iSBN13: parsedJson['identifier'],
      type: parsedJson['type'],
    );
  }
}

以及class的布局和使用:

Column(
              mainAxisSize: MainAxisSize.min,
              // crossAxisAlignment: CrossAxisAlignment.start,
              children: <Widget>[
                Flexible(
                  fit: FlexFit.loose,
                  child: Container(
                      margin: EdgeInsets.all(2.0),
                      child: Column(
                        mainAxisAlignment: MainAxisAlignment.start,
                        crossAxisAlignment: CrossAxisAlignment.start,
                        mainAxisSize: MainAxisSize.min,
                        children: <Widget>[
                          Container(
                              margin: EdgeInsets.only(
                                bottom: 3.0,
                                top: 30.0,
                              ),
                              child: Text(
                                'ISBN',
                                textAlign: TextAlign.left,
                                style: TextStyle(fontWeight: FontWeight.bold),
                              )),
                          Container(
                              width: 150.0,
                              margin: EdgeInsets.only(bottom: 10.0, top: 3.0),
                              child: Text(
                                'ISBN HERE',
                                softWrap: true,
                                overflow: TextOverflow.ellipsis,
                                maxLines: 3,
                              )),
                          Container(
                            margin: EdgeInsets.only(bottom: 3.0, top: 10.0),
                            child: Text('Author',
                                style: TextStyle(fontWeight: FontWeight.bold)),
                          ),
                          Container(
                            margin: EdgeInsets.only(bottom: 10.0, top: 3.0),
                            child: Text(
                              book.record.coverAuthors,
                            ),
                          ),
                          Container(
                            margin: EdgeInsets.only(bottom: 3.0, top: 10.0),
                            child: Text('Format',
                                style: TextStyle(fontWeight: FontWeight.bold)),
                          ),
                          Container(
                            margin: EdgeInsets.only(bottom: 10.0, top: 3.0),
                            child: Text(
                              volumelist.items[index].volumeinfo.printType,
                            ),
                          ),
                          Container(
                            margin: EdgeInsets.all(10.0),
                            child: Column(
                              children: <Widget>[
                                FlatButton(
                                  onPressed: () {},
                                  child: Text(
                                    'VIEW MORE DETAILS',
                                    style: TextStyle(color: Colors.deepPurple),
                                  ),
                                ),
                              ],
                            ),
                          )
                        ],
                      )),
                )

和 api 调用自身:

Future<VolumeJson> getRelateds() async {
    print('Im Starting');
    final jsonResponse =
        await http.get('https://www.googleapis.com/books/v1/volumes?q=${isbn}');

    var jsonBody = json.decode(jsonResponse.body);
    //print(jsonBody);

    volumelist = VolumeJson.fromJson(jsonBody);


  }