0% found this document useful (0 votes)
2 views

flutterlab8

Uploaded by

Kinza Fatima
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
2 views

flutterlab8

Uploaded by

Kinza Fatima
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 5

class Book {

final int id;


final String title;
final String author;
final String coverUrl;

Book({
required this.id,
required this.title,
required this.author,
required this.coverUrl,
});

// Factory constructor for creating a Book from JSON data


factory Book.fromJson(Map<String, dynamic> json) => Book(
id: json['id'],
title: json['title'],
author: json['author'],
coverUrl: json['coverUrl'],
);
}
import 'dart:convert';
import 'package:http/http.dart' as http;

Future<List<Book>> fetchBooks() async {


final url = Uri.parse('https://mockapi.example.com/books');

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';

class BookApp extends StatelessWidget {


const BookApp({super.key});

@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text('Books'),
),
body: const BookGrid(),
),
);
}
}

class BookGrid extends StatelessWidget {


const BookGrid({super.key});

@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'),
);
}
},
);
}
}

class BookCard extends StatelessWidget {


final Book book;

const BookCard({required this.book, super.key});

@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());
}

You might also like