What’s New in 2021 Volume 4: Flutter PDF Viewer | Syncfusion Blogs
Live Chat Icon For mobile
Live Chat Icon
Popular Categories.NET  (175).NET Core  (29).NET MAUI  (208)Angular  (109)ASP.NET  (51)ASP.NET Core  (82)ASP.NET MVC  (89)Azure  (41)Black Friday Deal  (1)Blazor  (220)BoldSign  (15)DocIO  (24)Essential JS 2  (107)Essential Studio  (200)File Formats  (67)Flutter  (133)JavaScript  (221)Microsoft  (119)PDF  (81)Python  (1)React  (101)Streamlit  (1)Succinctly series  (131)Syncfusion  (920)TypeScript  (33)Uno Platform  (3)UWP  (4)Vue  (45)Webinar  (51)Windows Forms  (61)WinUI  (68)WPF  (159)Xamarin  (161)XlsIO  (37)Other CategoriesBarcode  (5)BI  (29)Bold BI  (8)Bold Reports  (2)Build conference  (8)Business intelligence  (55)Button  (4)C#  (151)Chart  (132)Cloud  (15)Company  (443)Dashboard  (8)Data Science  (3)Data Validation  (8)DataGrid  (63)Development  (633)Doc  (8)DockingManager  (1)eBook  (99)Enterprise  (22)Entity Framework  (5)Essential Tools  (14)Excel  (41)Extensions  (22)File Manager  (7)Gantt  (18)Gauge  (12)Git  (5)Grid  (31)HTML  (13)Installer  (2)Knockout  (2)Language  (1)LINQPad  (1)Linux  (2)M-Commerce  (1)Metro Studio  (11)Mobile  (508)Mobile MVC  (9)OLAP server  (1)Open source  (1)Orubase  (12)Partners  (21)PDF viewer  (43)Performance  (12)PHP  (2)PivotGrid  (4)Predictive Analytics  (6)Report Server  (3)Reporting  (10)Reporting / Back Office  (11)Rich Text Editor  (12)Road Map  (12)Scheduler  (52)Security  (3)SfDataGrid  (9)Silverlight  (21)Sneak Peek  (31)Solution Services  (4)Spreadsheet  (11)SQL  (11)Stock Chart  (1)Surface  (4)Tablets  (5)Theme  (12)Tips and Tricks  (112)UI  (387)Uncategorized  (68)Unix  (2)User interface  (68)Visual State Manager  (2)Visual Studio  (31)Visual Studio Code  (19)Web  (597)What's new  (333)Windows 8  (19)Windows App  (2)Windows Phone  (15)Windows Phone 7  (9)WinRT  (26)
What’s New in 2021 Volume 4: Flutter PDF Viewer

What’s New in 2021 Volume 4: Flutter PDF Viewer

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:

  • Load password-protected and encrypted PDF documents.
  • Tile rendering.

Let’s look at them briefly.

Load password-protected and encrypted PDF documents

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.

Loading an Encrypted PDF Document in Flutter PDF Viewer
Loading an Encrypted PDF Document in Flutter PDF Viewer

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.

Customizing password dialog

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;
            }
          }
        },
      ),
    );
  }
}
Customizing the Password Dialog in Flutter PDF Viewer
Customizing the Password Dialog in Flutter PDF Viewer

Tile rendering

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.

Tile Rendering Feature in Flutter PDF Viewer
Tile Rendering Feature in Flutter PDF Viewer

Conclusion

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 forumsupport portal, or feedback portal. We are always happy to assist you!

Related blogs

Tags:

Share this post:

Popular Now

Be the first to get updates

Subscribe RSS feed

Be the first to get updates

Subscribe RSS feed