photo_view

repository·main·Indexed 24 days ago

https://github.com/bluefireteam/photo_view

A customizable Flutter widget for displaying zoomable and pannable images or arbitrary widgets. It includes PhotoView for basic zooming, PhotoViewGallery for swipable image galleries, and controllers like PhotoViewController and PhotoViewScaleStateController to programmatically manage zoom level, position, and rotation.

Tokens
3.5K
Snippets
6
Records
20
Agent score
84%

What's inside photo_view

  1. Control PhotoView state with controllers

    main

    To interact with or programmatically change the internal state of a PhotoView (such as zoom level or position), use the following controllers:

    • PhotoViewController: Used to interact with the view's internal state.
    • PhotoViewScaleStateController: Used to manage and listen to scale state changes.

    When these controllers are passed to a PhotoView widget, you can listen to state updates via a Stream and trigger changes externally.

  2. Use the PhotoView widget for basic image zooming

    main

    The PhotoView widget allows users to zoom and pan images using pinch, rotate, and drag gestures. It requires an imageProvider (such as AssetImage or NetworkImage).

    @override
    Widget build(BuildContext context) {
      return Container(
        child: PhotoView(
          imageProvider: AssetImage("assets/large-image.jpg"),
        )
      );
    }
  3. Create an image gallery with PhotoViewGallery

    main

    To display multiple images that a user can swipe through, use PhotoViewGallery.builder. This approach uses PhotoViewGalleryPageOptions to configure each page in the gallery, allowing you to set the imageProvider, initialScale, and heroAttributes for each item.

    import 'package:photo_view/photo_view.dart';
    import 'package:photo_view/photo_view_gallery.dart';
    // ...
    
    @override
    Widget build(BuildContext context) {
      return Container(
        child: PhotoViewGallery.builder(
          scrollPhysics: const BouncingScrollPhysics(),
          builder: (BuildContext context, int index) {
            return PhotoViewGalleryPageOptions(
              imageProvider: AssetImage(widget.galleryItems[index].image),
              initialScale: PhotoViewComputedScale.contained * 0.8,
              heroAttributes: PhotoViewHeroAttributes(tag: galleryItems[index].id),
            );
          },
          itemCount: galleryItems.length,
          loadingBuilder: (context, event) => Center(
            child: Container(
              width: 20.0,
              height: 20.0,
              child: CircularProgressIndicator(
                value: event == null
                    ? 0
                    : event.cumulativeBytesLoaded / event.expectedTotalBytes,
              ),
            ),
          ),
          backgroundDecoration: widget.backgroundDecoration,
          pageController: widget.pageController,
          onPageChanged: onPageChanged,
        )
      );
    }
  4. Use a custom child in PhotoViewCore

    main

    If you want to display something other than a standard Image widget (for example, a complex composition or a video player), you can use the PhotoViewCore.customChild constructor. This allows you to pass a customChild widget while still benefiting from the library's gesture handling, scaling, and rotation logic.

    When using customChild, the imageProvider parameter is not required.

    // Example of the customChild constructor pattern
    const PhotoViewCore.customChild({
        Key? key,
        required this.customChild,
        required this.backgroundDecoration,
        this.heroAttributes,
        required this.enableRotation,
        this.onTapUp,
        this.onTapDown,
        this.onScaleEnd,
        this.gestureDetectorBehavior,
        required this.controller,
        required this.scaleBoundaries,
        required this.scaleStateCycle,
        required this.scaleStateController,
        required this.basePosition,
        required this.tightMode,
        required this.filterQuality,
        required this.disableGestures,
        required this.enablePanAlways,
        required this.strictScale,
      });
  5. Use PhotoViewScaleStateController to manage scale states

    main

    The PhotoViewScaleStateController is used to manage and track the current PhotoViewScaleState. This state represents the step in the PhotoView.scaleStateCycle (e.g., triggered by double-tap gestures).

    Key functionalities:

    • Update State: Use the scaleState setter to change the current state. This will notify listeners and emit the new state through the stream.
    • Observe Changes: Listen to outputScaleStateStream to react to state changes.
    • Track History: The controller maintains prevScaleState to allow checking if the state has changed via hasChanged.
    • Lifecycle: Since this is a controller, you must call dispose() when it is no longer needed to close streams and remove listeners.

    Note: While addIgnorableListener exists, it is recommended to use outputScaleStateStream for better performance.

  6. Configure PhotoViewCore with an ImageProvider

    main

    The PhotoViewCore widget is the internal engine of the library, but it defines the primary configuration surface for displaying images. When using the standard constructor, you must provide an imageProvider and several configuration parameters to manage scale, rotation, and gestures.

    Key configuration properties include:

    • imageProvider: The ImageProvider to be displayed.
    • backgroundDecoration: A Decoration for the background (defaults to black).
    • scaleBoundaries: Defines minScale, maxScale, and initialScale.
    • controller: A PhotoViewControllerBase to manage the view state.
    • scaleStateController: A PhotoViewScaleStateController to track the current scale state.
    • enableRotation: Boolean to allow/disallow rotation gestures.
    • strictScale: If true, scale updates are ignored if they exceed scaleBoundaries.
    • enablePanAlways: If true, allows panning even when not scaled.
    • filterQuality: Controls the FilterQuality of the image.
    // Note: This is a conceptual representation of the PhotoViewCore constructor
    // as it is an internal implementation detail, but it defines the required config surface.
    const PhotoViewCore({
      required this.imageProvider,
      required this.backgroundDecoration,
      required this.semanticLabel,
      required this.gaplessPlayback,
      required this.heroAttributes,
      required this.enableRotation,
      required this.onTapUp,
      required this.onTapDown,
      required this.onScaleEnd,
      required this.gestureDetectorBehavior,
      required this.controller,
      required this.scaleBoundaries,
      required this.scaleStateCycle,
      required this.scaleStateController,
      required this.basePosition,
      required this.tightMode,
      required this.filterQuality,
      required this.disableGestures,
      required this.enablePanAlways,
      required this.strictScale,
    });
  7. Handle PhotoView gesture callbacks

    main

    You can intercept user interactions through several callback properties in the PhotoViewCore configuration:

    • onTapUp: Called when a tap is completed. Receives (BuildContext, TapUpDetails, PhotoViewControllerValue).
    • onTapDown: Called when a tap begins. Receives (BuildContext, TapDownDetails, PhotoViewControllerValue).
    • onScaleEnd: Called when a scale/pinch gesture ends. Receives (BuildContext, ScaleEndDetails, PhotoViewControllerValue).
  8. Use PhotoViewController to manage and observe photo state

    main

    The PhotoViewController is the default implementation for managing the state of a PhotoView widget. It allows you to programmatically control and observe the image's position, scale, rotation, and rotationFocusPoint.

    Key Lifecycle Note: You must call dispose() on the controller when it is no longer needed to close streams and remove listeners to prevent memory leaks.

  9. PhotoViewScaleStateController API Reference

    main

    The PhotoViewScaleStateController provides the following public interface for managing the scale state of a photo view:

    MemberTypeDescription
    scaleStatePhotoViewScaleState (getter/setter)The current scale state. Setting this notifies listeners and the stream.
    prevScaleStatePhotoViewScaleStateThe state value before the last change.
    outputScaleStateStreamStream<PhotoViewScaleState>A broadcast stream that emits the current scaleState whenever it changes.
    hasChangedbool (getter)Returns true if prevScaleState is different from scaleState.
    isZoomingbool (getter)Returns true if the state is PhotoViewScaleState.zoomedIn or PhotoViewScaleState.zoomedOut.
    reset()voidResets the scaleState to PhotoViewScaleState.initial.
    dispose()voidCloses the internal stream controller and disposes of the notifier. Must be called to prevent memory leaks.