pdf_bookshelf_viewer 0.1.5
pdf_bookshelf_viewer: ^0.1.5 copied to clipboard
A Flutter package for displaying PDFs in a beautiful bookshelf-style list with realistic page-turning animations.
PDF Bookshelf Viewer #
A beautiful Flutter package that displays PDFs in a bookshelf-style list with realistic page-turning animations and modern loading capabilities.
✨ Features #
📚 Bookshelf-Style Display #
- Beautiful wooden shelf design with realistic textures
- 3D book appearance with shadows and depth
- Customizable books per shelf
- Auto-generated book colors based on titles
📖 Page-Turning Animation #
- Realistic 3D page flip effect
- Smooth animations with gesture support
- Tap left/right to navigate pages
- Page indicator display
🌐 Multiple PDF Sources #
- Network URLs: Download PDFs from any HTTP/HTTPS URL
- Firebase Storage: Integrate with Firebase Cloud Storage
- App Assets: Bundle PDFs with your app
- Local Files: Load PDFs from device storage
⚡ Modern Features #
- Automatic Caching: Downloaded PDFs are cached for offline access
- Download Progress: Real-time progress indicators
- Error Handling: Graceful error states with retry functionality
- Offline Support: Access cached PDFs without internet
- Cache Management: Clear cache and monitor storage usage
📦 Installation #
Add this to your package's pubspec.yaml file:
dependencies:
pdf_bookshelf_viewer: ^0.1.5
Then run:
flutter pub get
🚀 Quick Start #
Basic Example #
import 'package:flutter/material.dart';
import 'package:pdf_bookshelf_viewer/pdf_bookshelf_viewer.dart';
class MyBookshelf extends StatelessWidget {
@override
Widget build(BuildContext context) {
final books = [
PdfBook(
title: 'Flutter Guide',
source: PdfSource.network('https://example.com/flutter.pdf'),
author: 'John Doe',
),
PdfBook(
title: 'Dart Basics',
source: PdfSource.asset('assets/pdfs/dart.pdf'),
author: 'Jane Smith',
),
];
return Scaffold(
appBar: AppBar(title: Text('My Bookshelf')),
body: BookshelfView(
books: books,
onBookTap: (book) {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => PdfPageFlipViewer(
pdfSource: book.source,
title: book.title,
),
),
);
},
),
);
}
}
📖 Usage Examples #
Loading PDFs from Different Sources #
1. Network URL
PdfBook(
title: 'My Document',
source: PdfSource.network('https://example.com/document.pdf'),
)
2. Network URL with Headers
PdfBook(
title: 'Protected Document',
source: PdfSource.network(
'https://api.example.com/document.pdf',
headers: {'Authorization': 'Bearer YOUR_TOKEN'},
),
)
3. Firebase Storage
// Make sure to initialize Firebase first
PdfBook(
title: 'Firebase PDF',
source: PdfSource.firebase('pdfs/document.pdf'),
)
// With custom bucket
PdfBook(
title: 'Custom Bucket PDF',
source: PdfSource.firebase(
'pdfs/document.pdf',
bucket: 'gs://your-custom-bucket',
),
)
4. App Assets
// Add PDF to pubspec.yaml assets first
PdfBook(
title: 'Bundled PDF',
source: PdfSource.asset('assets/pdfs/guide.pdf'),
)
5. Local File
PdfBook(
title: 'Local Document',
source: PdfSource.file('/path/to/local/file.pdf'),
)
Customizing the Bookshelf #
BookshelfView(
books: books,
onBookTap: _handleBookTap,
booksPerShelf: 4, // Number of books per row
shelfHeight: 220, // Height of each shelf
backgroundColor: Color(0xFFD4A574), // Custom wood color
)
PDF Viewer Options #
PdfPageFlipViewer(
pdfSource: PdfSource.network('https://example.com/doc.pdf'),
title: 'Document Title',
initialPage: 0, // Start at first page
forceRefresh: false, // Set true to ignore cache
)
Cache Management #
final pdfLoader = PdfLoaderService();
// Get cache size
final cacheSize = await pdfLoader.getCacheSize();
print('Cache size: ${cacheSize / (1024 * 1024)} MB');
// Clear all cache
await pdfLoader.clearCache();
// Remove specific PDF from cache
await pdfLoader.removeCachedPdf('https://example.com/document.pdf');
Manual PDF Loading with Progress #
final pdfLoader = PdfLoaderService();
final localPath = await pdfLoader.loadPdf(
PdfSource.network('https://example.com/large-document.pdf'),
onProgress: (progress) {
print('Download progress: ${(progress * 100).toStringAsFixed(0)}%');
},
forceRefresh: false, // Use cached version if available
);
print('PDF saved at: $localPath');
Lazy Loading Source #
You can provide books without a source and load it when the user taps on the book:
BookshelfView(
books: [
PdfBook(
title: 'Lazy Book',
// source is optional
pageCount: 150,
dimensions: '20x30 cm',
),
],
onObtainSource: (book) async {
// Fetch source asynchronously
await Future.delayed(Duration(seconds: 1));
return PdfSource.network('https://example.com/${book.title}.pdf');
},
)
🎨 Components #
PdfBook Model #
Represents a PDF book with metadata:
PdfBook(
title: 'Book Title', // Required
source: PdfSource.network(...), // Required
author: 'Author Name', // Optional
coverImage: 'cover.png', // Optional
PdfBook(
title: 'Book Title', // Required
source: PdfSource.network(...), // Optional
author: 'Author Name', // Optional
coverImage: 'cover.png', // Optional
description: 'Description', // Optional
pageCount: 120, // Optional
dimensions: '15 x 22 cm', // Optional
weight: '0.5 kg', // Optional
)
PdfSource #
Defines where to load the PDF from:
PdfSource.network(url, {headers})- HTTP/HTTPS URLPdfSource.firebase(path, {bucket})- Firebase StoragePdfSource.asset(path)- App assetsPdfSource.file(path)- Local file system
BookshelfView Widget #
Displays books in a bookshelf layout:
| Parameter | Type | Default | Description |
|---|---|---|---|
books |
List<PdfBook> |
required | List of books to display |
onBookTap |
Function(PdfBook)? |
null | Callback when book is tapped |
onObtainSource |
Future<PdfSource?> Function(PdfBook)? |
null | Callback to lazy load source |
booksPerShelf |
int |
3 | Books per shelf row |
shelfHeight |
double |
200 | Height of each shelf |
backgroundColor |
Color |
Wood color | Background color |
PdfPageFlipViewer Widget #
PDF viewer with page-turning animation:
| Parameter | Type | Default | Description |
|---|---|---|---|
pdfSource |
PdfSource |
required | PDF source |
title |
String? |
null | Title in app bar |
initialPage |
int |
0 | Starting page number |
forceRefresh |
bool |
false | Ignore cache |
🔧 Firebase Setup #
To use Firebase Storage:
- Add Firebase to your Flutter app
- Initialize Firebase in
main.dart:
import 'package:firebase_core/firebase_core.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp();
runApp(MyApp());
}
- Configure Firebase Storage rules
- Use
PdfSource.firebase()to load PDFs
📱 Platform Support #
| Platform | Support | Notes |
|---|---|---|
| Android | ✅ Full | All features supported |
| iOS | ✅ Full | All features supported |
| Web | ⚠️ Limited | PDF rendering may vary |
| Desktop | ⚠️ Limited | Experimental support |
🎯 Requirements #
- Flutter SDK: >=3.0.0
- Dart SDK: >=3.0.0
📸 Screenshots #
Coming soon
🤝 Contributing #
Contributions are welcome! Please feel free to submit a Pull Request.
📄 License #
This project is licensed under the MIT License - see the LICENSE file for details.
🙏 Credits #
- Uses flutter_pdfview for PDF rendering
- Uses dio for efficient downloads
- Uses firebase_storage for Firebase integration
📚 Example App #
Run the example app to see all features in action:
cd example
flutter run
The example demonstrates:
- Loading PDFs from network URLs
- Firebase Storage integration
- Asset-bundled PDFs
- Cache management
- Error handling and retry
- Download progress indicators
👨💻 Author #
Developed by TechSukras
🐛 Issues #
If you encounter any issues, please file them on the GitHub issue tracker.