Zoom Image in Flutter - InteractiveViewer Widget

The image sharing apps, shopping apps, etc. have image zoom functionality required to see the image in detail. Today, we will learn to implement the same with the help of a widget, InteractiveViewer.

This widget allows us to implement our application's zooming and panning features. Moreover, we don't need to install any other package.

Using InteractiveViewer Widget

We use this widget as follows:

InteractiveViewer(
  child: Image.network(
    'https://images.pexels.com/photos/1054655/pexels-photo-1054655.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=1',
  ),
),

Properties of the Widget

The properties often come into use when we want to customize the widget. Here is the List of all the properties that the widget has.

  • child( Widget ): It is the only required property and here we need to pass the child widget.

  • clipBehavior( Clip ): Here we provide the type of Image clipping. The default value is Clip.hardEdge,

  • alignPanAxis( bool ): If true, panning is only allowed in the direction of the horizontal or vertical axis. The default value is false,

  • boundaryMargin( EdgeInsets ): It us the boundary for the visible boundaries of the child widget. The default value is EdgeInsets.zero,

  • constrained( bool ): It asks whether the normal size constraints at this point in the widget tree are applied to the child. The default value is true,

  • maxScale( double ): This property caps the scaling up or zooming into the widget. The default value is 2.5.

  • minScale( double ): This property caps the scaling down or zooming out of the widget. The default value is 0.8,

  • onInteractionEnd( ScaleEndDetails ): It is called when the user ends a pan or scale gesture on the widget.

  • onInteractionStart( ScaleStartDetails ): It is called when the user starts a pan or scale gesture on the widget.

  • onInteractionUpdate( ScaleUpdateDetails ): It is called when the user updates a pan or scale gesture on the widget.

  • panEnabled( bool ): If set to true, we can pan around the widget. The default value is true.

  • scaleEnabled( bool ): If set to true, we can scale the widget. The default value is true.

  • scaleFactor( double ): It determines the amount of scale to be performed per pointer scroll. The default value is 200.0,

  • transformationController( TransformationController ): Whenever the child is transformed, the [Matrix4] value is updated and all listeners are notified. If the value is set, InteractiveViewer will update to respect the new value.

  • Basic Example

    In the following example, we have a NetworkImage and we are panning, scaling the image with the help of InteractiveViewer.

    main.dart

      import 'package:flutter/material.dart';
    
      void main() {
        runApp(const MyApp());
      }
    
      class MyApp extends StatelessWidget {
        const MyApp({Key? key}) : super(key: key);
    
        // This widget is the root of your application.
        @override
        Widget build(BuildContext context) {
          return MaterialApp(
            title: 'AllAboutFlutter',
            theme: ThemeData(
              primarySwatch: Colors.blue,
            ),
            home: const ImageZoom(),
          );
        }
      }
    
      class ImageZoom extends StatelessWidget {
        const ImageZoom({Key? key}) : super(key: key);
    
        @override
        Widget build(BuildContext context) {
          return Scaffold(
            appBar: AppBar(
              title: const Text('Image Zoom'),
            ),
            body: Center(
              child: InteractiveViewer(
                boundaryMargin: const EdgeInsets.all(20.0),
                minScale: 0.1,
                maxScale: 1.6,
                child: Image.network(
                  'https://images.pexels.com/photos/1054655/pexels-photo-1054655.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=1',
                ),
              ),
            ),
          );
        }
      }
    

    Output

    Disabling the Constrained

    On disabling the constrained, we receive the widget in full size.

    main.dart

      import 'package:flutter/material.dart';
    
      void main() {
        runApp(const MyApp());
      }
    
      class MyApp extends StatelessWidget {
        const MyApp({Key? key}) : super(key: key);
    
        // This widget is the root of your application.
        @override
        Widget build(BuildContext context) {
          return MaterialApp(
            title: 'AllAboutFlutter',
            theme: ThemeData(
              primarySwatch: Colors.blue,
            ),
            home: const ImageZoom(),
          );
        }
      }
    
      class ImageZoom extends StatelessWidget {
        const ImageZoom({Key? key}) : super(key: key);
    
        @override
        Widget build(BuildContext context) {
          return Scaffold(
            appBar: AppBar(
              title: const Text('Image Zoom'),
            ),
            body: Center(
              child: InteractiveViewer(
                boundaryMargin: const EdgeInsets.all(20.0),
                minScale: 0.1,
                maxScale: 3,
                constrained: false,
                child: Image.network(
                  'https://images.pexels.com/photos/1054655/pexels-photo-1054655.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=1',
                ),
              ),
            ),
          );
        }
      }
    

    Output

Did you find this article valuable?

Support All About Flutter | Flutter and Dart by becoming a sponsor. Any amount is appreciated!