TL;DR: Effortlessly manage and navigate multiple PDF files simultaneously with the multi-tabbed Flutter PDF Viewer. This powerful tool provides a seamless experience, allowing users to switch between documents while enhancing productivity and streamlining workflows efficiently.
In document-processing applications, users often need to interact with multiple PDFs simultaneously for comparison, referencing, or multitasking.
While the Syncfusion Flutter PDF Viewer is fantastic for viewing individual documents, there are times when handling several PDFs in the same interface is essential. Users crave the flexibility to open and navigate different documents without losing context, like their scroll position or zoom level.
To meet this demand, we can enhance the Flutter PDF Viewer by implementing a tab-based interface. This approach allows users to switch between PDFs quickly and efficiently, creating a seamless experience akin to viewing multiple documents side by side.
In this blog, we’ll explore how to elevate your existing PDF viewing capabilities in Flutter by building a multi-tabbed PDF Viewer. This innovative solution empowers users to open and manage several PDFs effortlessly, making multitasking a breeze.
Advantages of multi-tabbed PDF Viewer
Here are some of the advantages of this approach:
- Multi-document support: Open multiple PDFs, each in its own tab.
- Quick navigation: Easily switch between different PDF documents using tabs.
- Individual PDF controls: Each PDF Viewer instance maintains its own zoom, navigation, and rendering state.
- Flexible file management: Easily open or close PDF files as needed, providing a flexible and tailored viewing experience.
Setting up the Flutter PDF Viewer
First, we need to install the Syncfusion Flutter PDF Viewer package by following these steps:
- Add the following code to your pubspec.yaml file to add the Syncfusion Flutter PDF Viewer dependency.
syncfusion_flutter_pdfviewer: ^xx.x.xx # Replace xx.x.xx with the latest version
2.Next, you need to import the PDF Viewer package. Add the following import statement to your Dart file.
import 'package:syncfusion_flutter_pdfviewer/pdfviewer.dart';
3.Once the package has been imported, initialize the SfPdfVieweras a child of any widget. For more details, refer to the getting started documentation.
Steps to implement the multi-tabbed feature in Flutter PDF Viewer
Step 1: Define the Tab bar and Tab controller
The TabBar widget will display tabs representing each PDF document, while TabBarView holds the actual PDF Viewer instances for each open document. Then, the TabController will manage tab switching and update the interface as new documents are opened or closed.
First, we’ll define the main widget ( PdfTabView ) to handle the tab setup, navigation, and interaction with PDF documents.
Refer to the following code example.
class PdfTabView extends StatefulWidget {
const PdfTabView({super.key});
@override
State createState() => _PdfTabViewState();
}
class _PdfTabViewState extends State with TickerProviderStateMixin {
late TabController _tabController; // Controller for managing tab navigation.
late final List _openedFiles; // List to hold the opened PDF files.
@override
void initState() {
super.initState(); // Call the super class's initState method.
_openedFiles = []; // Initialize the list of opened PDF files.
_tabController = TabController(length: _openedFiles.length, vsync: this); // Initialize the TabController with the current number of opened files.
}
@override
void dispose() {
_tabController.dispose(); // Dispose of the TabController to free resources.
super.dispose(); // Call the super class's dispose method.
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: TabBarView(
controller: _tabController, // Set the controller for the TabBarView.
children: _openedFiles.map((PdfFile file) {
// Create a list of PdfView widgets for each opened PDF file.
return PdfView(
key: file.key, // Unique key for the PdfView.
bytes: file.bytes, // PDF file content as bytes.
);
}).toList(),
),
appBar: AppBar(
actions: [
// Button to open a new PDF file.
OutlinedButton(onPressed: _addNewTab, child: const Text('Open PDF')),
],
bottom: TabBar(
controller: _tabController, // Set the controller for the TabBar.
tabs: _openedFiles.map((PdfFile file) {
// Create a tab for each opened PDF file.
return Tab(text: file.name);
}).toList(),
),
),
);
}
}
Step 2: Display the PDF file in the tab using Flutter PDF Viewer
In the TabBarView, each tab displays a PDF using the SfPdfViewer widget. Here, we’ll define a custom widget named PdfView to handle PDF rendering for each tab, as shown in the following code example.
class PdfView extends StatefulWidget {
const PdfView({super.key, required this.bytes});
// The PDF file as bytes
final Uint8List bytes;
@override
State createState() => _PdfViewState();
}
class _PdfViewState extends State{
@override
Widget build(BuildContext context) {
return SfPdfViewer.memory(
widget.bytes,
);
}
}
Step 3: Opening a new PDF file in its own tab
When a user selects a new PDF file, we create a new tab to display it. This allows users to dynamically open new PDFs in their own tabs, enhancing the multitasking experience.
Refer to the following code example.
Future _addNewTab() async {
// Prompt the user to pick a PDF file and retrieve it as bytes.
final Uint8List? bytes = await _pickPdf();
// If a file was selected, add it to the open files and update the tab controller.
if (bytes != null) {
setState(() {
_openedFiles.add(PdfFile('fileName', bytes, UniqueKey()));
_tabController = TabController(
length: _openedFiles.length,
vsync: this,
initialIndex: _openedFiles.length - 1,
);
});
}
}
Step 4: Closing a PDF file
To remove a tab corresponding to a closed PDF file and update the tab controller, we’ll define a method that manages this functionality.
When a user closes a tab, we ensure that the corresponding PDF file is removed from the list and that the tab controller is updated accordingly.
Refer to the following code example.
void _removeTab(int index) {
// Remove the PDF file at the specified index.
_openedFiles.removeAt(index);
// Dispose of the previous TabController to free resources.
_tabController.dispose();
// Update the TabController with the new length of opened files.
setState(() {
_tabController = TabController(
length: _openedFiles.length,
vsync: this,
);
});
}
Step 5: Preserving the PDF Viewer state
To ensure that the PDF Viewer retains its state (such as zoom level and scroll position) when switching between tabs, we utilize the AutomaticKeepAliveClientMixin. This approach prevents the SfPdfViewer widget from being disposed of when changing tabs, maintaining the user’s viewing experience.
Refer to the following code example.
class _PdfViewState extends State with AutomaticKeepAliveClientMixin {
@override
bool get wantKeepAlive => true;
@override
Widget build(BuildContext context) {
// Call super.build to maintain the keep-alive state.
super.build(context);
return SfPdfViewer.memory(
widget.bytes,
);
}
}
That’s it! Now, we’ve implemented a multi-tab PDF Viewer in Flutter that allows users to open multiple PDF files seamlessly, manage tabs, and preserve the viewer state for an enhanced experience.
Refer to the following output GIF image.
GitHub reference
For more details, refer to the multi-tabbed Flutter PDF Viewer GitHub demo.
To run the demo, please follow these steps:
- Download the demo from the GitHub repository and run the app.
- A default PDF file will be displayed and loaded from the Assets folder.
- To add a new PDF file, click the Open PDF button located at the top right. The document will open in a new tab.
- To close a PDF file, click the close option available in the respective tab.
Conclusion
Thanks for reading! Following this approach, you can build a multi-tabbed Flutter PDF Viewer that allows users to manage and view multiple PDF documents simultaneously. This solution not only makes it easier to work across multiple PDFs but also provides an intuitive and smooth experience by maintaining states across tabs and allowing dynamic document management.
If you’re an existing Syncfusion user, you can download the latest version of Essential Studio® from the License and Downloads page. For new users, we offer a 30-day free trial so you can explore these powerful features yourself.
If you need any help, don’t hesitate to reach out through our support forum, support portal, or feedback portal. We’re always here to assist you!