The Syncfusion Flutter PDF Viewer (SfPdfViewer) widget lets you view PDF documents seamlessly and efficiently in Android, iOS, web, and macOS platforms. It has highly interactive and customizable features such as magnification, virtual scrolling, page navigation, and bookmark navigation.
Adding to these, we have included the following new, user-friendly features in our Flutter PDF Viewer for the 2021 Volume 4 release:
Let’s look at them briefly.
Now, Flutter PDF Viewer provides support to load password-protected PDF documents. It allows us to load and open PDF documents encrypted with AES and RC4 encryption algorithms.
When we load a password-protected PDF document with an invalid or empty password, the Flutter PDF Viewer will display the Password Protected dialog. In that, we have to use the proper password to open the encrypted PDF. To open an encrypted PDF document, use the password property.
Refer to the following image.
We can customize the style (theme) of the built-in password dialog using the passwordDialogStyle property.
Note:For more details, refer to the Specialized theme widget in Flutter PDF Viewer documentation.
We can customize the entire password dialog by disabling the built-in dialog and creating a new dialog. To disable the built-in password dialog, set the canShowPasswordDialog property as false.
The following code example illustrates how to display a customized password dialog in the Flutter PDF Viewer.
void main() { runApp(MaterialApp(home: CustomPasswordDialog())); } class CustomPasswordDialog extends StatefulWidget { @override _CustomPasswordDialogState createState() => _CustomPasswordDialogState(); } class _CustomPasswordDialogState extends State<CustomPasswordDialog> { String? _password; final GlobalKey<FormFieldState> _formKey = GlobalKey<FormFieldState>(); final TextEditingController _textFieldController = TextEditingController(); final FocusNode _passwordDialogFocusNode = FocusNode(); bool _hasPasswordDialog = false; String _errorText = ''; @override Widget build(BuildContext context) { final Orientation orientation = kIsWeb ? Orientation.portrait : MediaQuery.of(context).orientation; return Scaffold( appBar: AppBar( title: Text("Custom password dialog"), toolbarHeight: 56, ), body: SfPdfViewer.network( "https://cdn.syncfusion.com/content/PDFViewer/encrypted.pdf", canShowPasswordDialog: false, password: _password, onDocumentLoaded: (details) { Navigator.pop(context); _hasPasswordDialog = false; _passwordDialogFocusNode.unfocus(); }, onDocumentLoadFailed: (details) { if (details.description.contains('password')) { if (details.description.contains('invalid') && _hasPasswordDialog) { _errorText = "Invalid password !!"; _formKey.currentState?.validate(); _textFieldController.clear(); _passwordDialogFocusNode.requestFocus(); } else { _errorText = ''; // Creating custom password dialog. showDialog<String>( context: context, builder: (BuildContext context) => SafeArea( minimum: EdgeInsets.only(left: 10,right: 10), child: AlertDialog( scrollable: true, insetPadding: EdgeInsets.zero, contentPadding: orientation == Orientation.portrait ? const EdgeInsets.all(24) : const EdgeInsets.only( top: 0, right: 24, left: 24, bottom: 0), buttonPadding: orientation == Orientation.portrait ? const EdgeInsets.all(8) : const EdgeInsets.all(4), title: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: <Widget>[ Text( 'Password required', style: TextStyle( fontFamily: 'Roboto', fontSize: 20, fontWeight: FontWeight.w500, color: Theme.of(context) .colorScheme .onSurface .withOpacity(0.87), ), ), SizedBox( height: 36, width: 36, child: RawMaterialButton( onPressed: () { _textFieldController.clear(); Navigator.of(context).pop(); _hasPasswordDialog = false; _passwordDialogFocusNode.unfocus(); }, child: Icon( Icons.clear, color: Theme.of(context) .colorScheme .onSurface .withOpacity(0.6), size: 24, ), ), ), ], ), actionsPadding: EdgeInsets.only(top: 0), shape: const RoundedRectangleBorder( borderRadius: BorderRadius.all(Radius.circular(4.0))), content: SingleChildScrollView( child: SizedBox( child: Column(children: <Widget>[ Align( alignment: Alignment.centerLeft, child: Padding( padding: const EdgeInsets.fromLTRB(0, 0, 0, 30), child: Text( 'The document is password protected. Please enter a password.', style: TextStyle( fontFamily: 'Roboto', fontSize: 16, fontWeight: FontWeight.w400, color: Theme.of(context) .colorScheme .onSurface .withOpacity(0.6), ), ), ), ), Form( child: TextFormField( key: _formKey, controller: _textFieldController, focusNode: _passwordDialogFocusNode, obscureText: true, decoration: InputDecoration(hintText: 'Password hint: syncfusion', border: OutlineInputBorder(borderSide: BorderSide(color: Colors.blue)), focusedBorder: OutlineInputBorder(borderSide: BorderSide(color: Colors.blue))), obscuringCharacter: '#', onFieldSubmitted: (value) { setState(() { _password = value; }); }, validator: (value) { if (_errorText.isNotEmpty) return _errorText; return null; }, onChanged: (value) { _formKey.currentState?.validate(); _errorText = ''; }, ), ) ]))), actions: <Widget>[ Row( textDirection: TextDirection.rtl, children: [ TextButton( onPressed: () { Navigator.pop(context, 'Cancel'); _hasPasswordDialog = false; _passwordDialogFocusNode.unfocus(); }, child: const Text('CANCEL'), ), TextButton( onPressed: () { if (_textFieldController.text.isNotEmpty) { setState(() { _password = _textFieldController.text; }); } }, child: const Text('OK'), ) ], ) ], ), )); _hasPasswordDialog = true; } } }, ), ); } }
Whenever a PDF document is zoomed in, the PDF pages’ resolution should be increased so that pixelation can be avoided, and clarity of the content will be improved.
The new tile rendering feature in the PDF Viewer enhances the PDF pages’ clarity and readability. This feature renders the PDF page regions in high resolution when a user zooms in on them.
Thanks for reading! In this blog, we have seen the new features of the Syncfusion Flutter PDF Viewer available in the 2021 Volume 4 release. Details on these features are also available in our Release Notes and What’s New pages. Refer to our Flutter PDF Viewer documentation for complete details about the widget. Try out these features and leave your feedback in the comments section below!
Also, don’t miss our Flutter demos on GitHub, Google Play, and the App Store.
If you are an existing Syncfusion user, please download the latest version of Essential Studio from the License & Downloads page. If you aren’t a customer yet, you can try our 30-day free trial to check out these features.
You can contact us through our support forum, support portal, or feedback portal. We are always happy to assist you!