flutterlab8
flutterlab8
Book({
required this.id,
required this.title,
required this.author,
required this.coverUrl,
});
try {
final response = await http.get(url);
if (response.statusCode == 200) {
final List<dynamic> bookJson = jsonDecode(response.body);
return bookJson.map((json) => Book.fromJson(json)).toList();
} else {
throw Exception('Failed to load books. Status code:
${response.statusCode}');
}
} catch (e) {
throw Exception('Error fetching books: $e');
}
}
import 'package:flutter/material.dart';
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text('Books'),
),
body: const BookGrid(),
),
);
}
}
@override
Widget build(BuildContext context) {
return FutureBuilder<List<Book>>(
future: fetchBooks(),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return const Center(
child: CircularProgressIndicator(),
);
} else if (snapshot.hasError) {
return Center(
child: Text('Error: ${snapshot.error}'),
);
} else if (snapshot.hasData) {
final books = snapshot.data!;
return GridView.builder(
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
),
itemCount: books.length,
itemBuilder: (context, index) {
return BookCard(book: books[index]);
},
);
} else {
return const Center(
child: Text('No books available'),
);
}
},
);
}
}
@override
Widget build(BuildContext context) {
return Card(
child: Column(
children: [
Image.network(
book.coverUrl,
height: 100,
fit: BoxFit.cover,
),
Padding(
padding: const EdgeInsets.symmetric(vertical: 8.0),
child: Text(
book.title,
style: const TextStyle(fontWeight: FontWeight.bold),
),
),
Text(book.author),
],
),
);
}
}
void main() {
runApp(const BookApp());
}