top of page

Zoom Image in Flutter - InteractiveViewer Widget

Updated: Feb 5

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

Basic Example InteractiveViewer
Basic Example InteractiveViewer


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

Disabled Constrained InteractiveViewer
Disabled Constrained InteractiveViewer


bottom of page