I am reading Chapter 15 of the Flutter Cookbook – Second Edition by Simone Alessandria. I follow the following steps in creating those code:
book_list_screen.dart
import 'package:flutter/material.dart';
import '../models/book.dart';
import '../data/http_helper.dart';
class BookListScreen extends StatefulWidget {
const BookListScreen({super.key});
@override
State<BookListScreen> createState() => _BookListScreenState();
}
class _BookListScreenState extends State<BookListScreen> {
List<Book> books = [];
List<Color> bgColors = [];
@override
Widget build(BuildContext context) {
bool isLargeScreen;
if (MediaQuery.of(context).size.width > 600) {
isLargeScreen = true;
} else {
isLargeScreen = false;
}
return Scaffold(
appBar: AppBar(title: const Text('Books')),
body: GridView.count(
childAspectRatio: isLargeScreen ? 8 : 5,
crossAxisCount: isLargeScreen ? 2 : 1,
children: List.generate(books.length, (index) {
return GestureDetector(
onTap: () => setColor(Colors.lightBlue, index),
onSecondaryTap: () => setColor(Colors.white, index),
onLongPress: () => setColor(Colors.white, index),
child: ColoredBox(
color:
bgColors.isNotEmpty ? bgColors[index] : Colors.white,
child: ListTile(
title: Text(books[index].title),
subtitle: Text(books[index].authors),
leading: CircleAvatar(
backgroundImage: (books[index].thumbnail) == ''
? null
: NetworkImage(books[index].thumbnail),
),
)));
})));
}
@override
void initState() {
super.initState();
final HttpHelper helper = HttpHelper();
helper.getBooks('flutter').then((List<Book> value) {
int i;
for (i = 0; i < value.length; i++) {
bgColors.add(Colors.white);
}
});
}
void setColor(Color color, int index) {
setState(() {
bgColors[index] = color;
});
}
}
http_helper.dart
import 'package:http/http.dart' as http;
import 'dart:convert';
import 'dart:async';
import 'package:http/http.dart';
import '../models/book.dart';
class HttpHelper {
static const String authority = 'www.googleapis.com';
static const path = '/books/v1/volumes';
Future<List<Book>> getBooks(String query) async {
Map<String, dynamic> params = {
'q': query,
'maxResults': '40',
};
Uri uri = Uri.https(authority, path, params);
Response result = await http.get(uri);
if (result.statusCode == 200) {
final jsonResponse = json.decode(result.body);
final booksMap = jsonResponse['items'];
List<Book> books = booksMap.map<Book>((i) => Book.fromJson(i)).toList();
return books;
} else {
return [];
}
}
}
book.dart
class Book {
final String id;
final String title;
final String authors;
final String thumbnail;
final String description;
const Book(
this.id, this.title, this.authors, this.thumbnail, this.description);
factory Book.fromJson(Map<String, dynamic> parsedJson) {
final String id = parsedJson['id'];
final String title = parsedJson['volumeInfo']['title'];
String image = parsedJson['volumeInfo']['imageLinks'] == null
? ''
: parsedJson['volumeInfo']['imageLinks']['thumbnail'];
image.replaceAll('http://', 'https://');
final String authors = (parsedJson['volumeInfo']['authors'] == null)
? ''
: parsedJson['volumeInfo']['authors'].toString();
final String description = (parsedJson['volumeInfo']['description'] == null)
? ''
: parsedJson['volumeInfo']['description'];
return Book(id, title, authors, image, description);
}
}
The book titles are displayed at the top when I run the app. Unfortunately, other information, such as the authors and thumbnails, is not visible at all. What could be the issue?
The full code can be found on the author’s GitHub