• Stars
    star
    1,908
  • Rank 24,300 (Top 0.5 %)
  • Language
    Dart
  • License
    MIT License
  • Created over 5 years ago
  • Updated 2 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

A powerful official extension library of image, which support placeholder(loading)/ failed state, cache network, zoom pan image, photo view, slide out page, editor(crop,rotate,flip), paint custom etc.

extended_image

pub package GitHub stars GitHub forks GitHub license GitHub issues flutter-candies

Language: English| 中文简体

A powerful official extension library of images, which supports placeholder(loading)/ failed state, cache network, zoom pan image, photo view, slide-out page, editor (crop, rotate, flip), paint custom etc.

Web demo for ExtendedImage

ExtendedImage is an third-party library that extends the functionality of Flutter's Image component. The main extended features are as follows:

Feature ExtendedImage Image
Cache network images locally and load from cache Supported Not supported
Compression display Supported, with additional options (compressionRatio and maxBytes) Supported, with cacheHeight, cacheWidth
Automatic release of image resources Supported Requires manual management
Scaling mode Supported Not supported
Editing mode Supported Not supported
Drag-to-dismiss effect for images in a page transition Supported Not supported

Table of contents

Import

  • null-safety
environment:
  sdk: '>=2.12.0 <3.0.0'
  flutter: '>=2.0'
dependencies:
  extended_image: ^4.0.0
  • non-null-safety

1.22.6 to 2.0, Flutter Api has breaking change,please use non-null-safety if you under 1.22.6.

environment:
  sdk: '>=2.6.0 <2.12.0'
  flutter: '>1.17.0 <=1.22.6'
dependencies:
  extended_image: ^3.0.0-non-null-safety

Cache Network

Simple use

You can use ExtendedImage.network as Image Widget

ExtendedImage.network(
  url,
  width: ScreenUtil.instance.setWidth(400),
  height: ScreenUtil.instance.setWidth(400),
  fit: BoxFit.fill,
  cache: true,
  border: Border.all(color: Colors.red, width: 1.0),
  shape: boxShape,
  borderRadius: BorderRadius.all(Radius.circular(30.0)),
  //cancelToken: cancellationToken,
)

Use ExtendedNetworkImageProvider

ExtendedNetworkImageProvider

   ExtendedNetworkImageProvider(
      this.url, {
      this.scale = 1.0,
      this.headers,
      this.cache: false,
      this.retries = 3,
      this.timeLimit,
      this.timeRetry = const Duration(milliseconds: 100),
      CancellationToken cancelToken,
    })  : assert(url != null),
          assert(scale != null),
          cancelToken = cancelToken ?? CancellationToken();
parameter description default
url The URL from which the image will be fetched. required
scale The scale to place in the [ImageInfo] object of the image. 1.0
headers The HTTP headers that will be used with [HttpClient.get] to fetch image from network. -
cache whether cache image to local false
retries the time to retry to request 3
timeLimit time limit to request image -
timeRetry the time duration to retry to request milliseconds: 100
cancelToken token to cancel network request CancellationToken()

you can create new provider and extends it with ExtendedProvider, and override instantiateImageCodec method. so that you can handle image raw data here (compress image).

Load State

Extended Image provide 3 states(loading,completed,failed), you can define your state widget with loadStateChanged call back.

loadStateChanged is not only for network, if your image need long time to load, you can set enableLoadState(default value is true for network and others are false) to true

img

Notice:

  • if you don't want to override any state, please return null in this case

  • if you want to override size or sourceRect, you can override it with ExtendedRawImage at completed state

  • if you want to add something (like animation) at completed state, you can override it with ExtendedImageState.completedWidget

  • ExtendedImageState.completedWidget is include gesture or editor, so that you would't miss them

/// custom load state widget if you want
    final LoadStateChanged loadStateChanged;

enum LoadState {
  //loading
  loading,
  //completed
  completed,
  //failed
  failed
}

  ///whether has loading or failed state
  ///default is false
  ///but network image is true
  ///better to set it's true when your image is big and take some time to ready
  final bool enableLoadState;

ExtendedImageState(LoadStateChanged call back)

parameter/method description default
extendedImageInfo image info -
extendedImageLoadState LoadState(loading,completed,failed) -
returnLoadStateChangedWidget if this is true, return widget which from LoadStateChanged function immediately(width/height/gesture/border/shape etc, will not effect on it) -
imageProvider ImageProvider -
invertColors invertColors -
imageStreamKey key of image -
reLoadImage() if image load failed,you can reload image by call it -
completedWidget return completed widget include gesture or editor -
loadingProgress return the loading progress for network image (ImageChunkEvent ) -
abstract class ExtendedImageState {
  void reLoadImage();
  ImageInfo get extendedImageInfo;
  LoadState get extendedImageLoadState;

  ///return widget which from LoadStateChanged function immediately
  bool returnLoadStateChangedWidget;

  ImageProvider get imageProvider;

  bool get invertColors;

  Object get imageStreamKey;

  Widget get completedWidget;
}

demo code

ExtendedImage.network(
  url,
  width: ScreenUtil.instance.setWidth(600),
  height: ScreenUtil.instance.setWidth(400),
  fit: BoxFit.fill,
  cache: true,
  loadStateChanged: (ExtendedImageState state) {
    switch (state.extendedImageLoadState) {
      case LoadState.loading:
        _controller.reset();
        return Image.asset(
          "assets/loading.gif",
          fit: BoxFit.fill,
        );
        break;

      ///if you don't want override completed widget
      ///please return null or state.completedWidget
      //return null;
      //return state.completedWidget;
      case LoadState.completed:
        _controller.forward();
        return FadeTransition(
          opacity: _controller,
          child: ExtendedRawImage(
            image: state.extendedImageInfo?.image,
            width: ScreenUtil.instance.setWidth(600),
            height: ScreenUtil.instance.setWidth(400),
          ),
        );
        break;
      case LoadState.failed:
        _controller.reset();
        return GestureDetector(
          child: Stack(
            fit: StackFit.expand,
            children: <Widget>[
              Image.asset(
                "assets/failed.jpg",
                fit: BoxFit.fill,
              ),
              Positioned(
                bottom: 0.0,
                left: 0.0,
                right: 0.0,
                child: Text(
                  "load image failed, click to reload",
                  textAlign: TextAlign.center,
                ),
              )
            ],
          ),
          onTap: () {
            state.reLoadImage();
          },
        );
        break;
    }
  },
)

Zoom Pan

img

ExtendedImage

parameter description default
mode image mode (none, gesture, editor) none
initGestureConfigHandler init GestureConfig when image is ready,for example, base on image width/height -
onDoubleTap call back of double tap under ExtendedImageMode.gesture -
extendedImageGestureKey you can handle zoom/pan by using this key manually -

GestureConfig

parameter description default
minScale min scale 0.8
animationMinScale the min scale for zooming then animation back to minScale when scale end minScale _ 0.8
maxScale max scale 5.0
animationMaxScale the max scale for zooming then animation back to maxScale when scale end maxScale _ 1.2
speed speed for zoom/pan 1.0
inertialSpeed inertial speed for zoom/pan 100
cacheGesture save Gesture state (for example in ExtendedImageGesturePageView, gesture state will not change when scroll back),remember clearGestureDetailsCache at right time false
inPageView whether in ExtendedImageGesturePageView false
initialAlignment init image rect with alignment when initialScale > 1.0 InitialAlignment.center
hitTestBehavior How to behave during hit tests HitTestBehavior.deferToChild
ExtendedImage.network(
  imageTestUrl,
  fit: BoxFit.contain,
  //enableLoadState: false,
  mode: ExtendedImageMode.gesture,
  initGestureConfigHandler: (state) {
    return GestureConfig(
        minScale: 0.9,
        animationMinScale: 0.7,
        maxScale: 3.0,
        animationMaxScale: 3.5,
        speed: 1.0,
        inertialSpeed: 100.0,
        initialScale: 1.0,
        inPageView: false,
        initialAlignment: InitialAlignment.center,
        );
  },
)

double tap animation

onDoubleTap: (ExtendedImageGestureState state) {
  ///you can use define pointerDownPosition as you can,
  ///default value is double tap pointer down postion.
  var pointerDownPosition = state.pointerDownPosition;
  double begin = state.gestureDetails.totalScale;
  double end;

  //remove old
  _animation?.removeListener(animationListener);

  //stop pre
  _animationController.stop();

  //reset to use
  _animationController.reset();

  if (begin == doubleTapScales[0]) {
    end = doubleTapScales[1];
  } else {
    end = doubleTapScales[0];
  }

  animationListener = () {
    //print(_animation.value);
    state.handleDoubleTap(
        scale: _animation.value,
        doubleTapPosition: pointerDownPosition);
  };
  _animation = _animationController
      .drive(Tween<double>(begin: begin, end: end));

  _animation.addListener(animationListener);

  _animationController.forward();
},

Editor

img

    ExtendedImage.network(
      imageTestUrl,
      fit: BoxFit.contain,
      mode: ExtendedImageMode.editor,
      extendedImageEditorKey: editorKey,
      initEditorConfigHandler: (state) {
        return EditorConfig(
            maxScale: 8.0,
            cropRectPadding: EdgeInsets.all(20.0),
            hitTestSize: 20.0,
            cropAspectRatio: _aspectRatio.aspectRatio);
      },
    );

ExtendedImage

parameter description default
mode image mode (none,gestrue,editor) none
initEditorConfigHandler init EditorConfig when image is ready. -
extendedImageEditorKey key of ExtendedImageEditorState to flip/rotate/get crop rect -

EditorConfig

parameter description default
maxScale max scale of zoom 5.0
cropRectPadding the padding between crop rect and image layout rect. EdgeInsets.all(20.0)
cornerSize size of corner shape (DEPRECATED! Use cornerPainter) Size(30.0, 5.0)
cornerColor color of corner shape (DEPRECATED! Use cornerPainter) primaryColor
lineColor color of crop line scaffoldBackgroundColor.withOpacity(0.7)
lineHeight height of crop line 0.6
editorMaskColorHandler call back of editor mask color base on pointerDown scaffoldBackgroundColor.withOpacity(pointerDown ? 0.4 : 0.8)
hitTestSize hit test region of corner and line 20.0
animationDuration auto center animation duration Duration(milliseconds: 200)
tickerDuration duration to begin auto center animation after crop rect is changed Duration(milliseconds: 400)
cropAspectRatio aspect ratio of crop rect null(custom)
initialCropAspectRatio initial aspect ratio of crop rect null(custom: initial crop rect will fill the entire image)
initCropRectType init crop rect base on initial image rect or image layout rect imageRect
cornerPainter corner shape ExtendedImageCropLayerPainterNinetyDegreesCorner()
hitTestBehavior How to behave during hit tests HitTestBehavior.deferToChild

crop aspect ratio

it's a double value, so it's easy for you to define by yourself. following are official values

class CropAspectRatios {
  /// no aspect ratio for crop
  static const double custom = null;

  /// the same as aspect ratio of image
  /// [cropAspectRatio] is not more than 0.0, it's original
  static const double original = 0.0;

  /// ratio of width and height is 1 : 1
  static const double ratio1_1 = 1.0;

  /// ratio of width and height is 3 : 4
  static const double ratio3_4 = 3.0 / 4.0;

  /// ratio of width and height is 4 : 3
  static const double ratio4_3 = 4.0 / 3.0;

  /// ratio of width and height is 9 : 16
  static const double ratio9_16 = 9.0 / 16.0;

  /// ratio of width and height is 16 : 9
  static const double ratio16_9 = 16.0 / 9.0;
}

crop layer painter

you can define your crop layer by override [EditorConfig.editorCropLayerPainter].

class EditorCropLayerPainter {
  const EditorCropLayerPainter();
  void paint(Canvas canvas, Size size, ExtendedImageCropLayerPainter painter) {
    paintMask(canvas, size, painter);
    paintLines(canvas, size, painter);
    paintCorners(canvas, size, painter);
  }

  /// draw crop layer corners
  void paintCorners(
      Canvas canvas, Size size, ExtendedImageCropLayerPainter painter) {
  }

  /// draw crop layer lines
  void paintMask(
      Canvas canvas, Size size, ExtendedImageCropLayerPainter painter) {
  }
  

  /// draw crop layer lines
  void paintLines(
      Canvas canvas, Size size, ExtendedImageCropLayerPainter painter) {
  } 
}

crop,flip,reset

  • add key for ExtendedImageEditorState

    final GlobalKey<ExtendedImageEditorState> editorKey =GlobalKey<ExtendedImageEditorState>();

  • rotate right

    editorKey.currentState.rotate(right: true);

  • rotate left

    editorKey.currentState.rotate(right: false);

  • flip

    editorKey.currentState.flip();

  • reset

    editorKey.currentState.reset();

crop data

dart library(stable)

  • add Image library into your pubspec.yaml, it's used to crop/rotate/flip image data
dependencies:
  image: any
  • get crop rect and raw image data from ExtendedImageEditorState
  ///crop rect base on raw image
  final Rect cropRect = state.getCropRect();

  var data = state.rawImageData;
  • convert raw image data to image library data.
  /// it costs much time and blocks ui.
  //Image src = decodeImage(data);

  /// it will not block ui with using isolate.
  //Image src = await compute(decodeImage, data);
  //Image src = await isolateDecodeImage(data);
  final lb = await loadBalancer;
  Image src = await lb.run<Image, List<int>>(decodeImage, data);
  • crop,flip,rotate data
  //clear orientation
  src = bakeOrientation(src);

  if (editAction.needCrop)
    src = copyCrop(src, cropRect.left.toInt(), cropRect.top.toInt(),
        cropRect.width.toInt(), cropRect.height.toInt());

  if (editAction.needFlip) {
    Flip mode;
    if (editAction.flipY && editAction.flipX) {
      mode = Flip.both;
    } else if (editAction.flipY) {
      mode = Flip.horizontal;
    } else if (editAction.flipX) {
      mode = Flip.vertical;
    }
    src = flip(src, mode);
  }

  if (editAction.hasRotateAngle) src = copyRotate(src, editAction.rotateAngle);
  • convert to original image data

output is raw image data, you can use it to save or any other thing.

  /// you can encode your image
  ///
  /// it costs much time and blocks ui.
  //var fileData = encodeJpg(src);

  /// it will not block ui with using isolate.
  //var fileData = await compute(encodeJpg, src);
  //var fileData = await isolateEncodeImage(src);
  var fileData = await lb.run<List<int>, Image>(encodeJpg, src);

native library(faster)

  • add ImageEditor library into your pubspec.yaml, it's used to crop/rotate/flip image data
dependencies:
  image_editor: any
  • get crop rect and raw image data from ExtendedImageEditorState
  ///crop rect base on raw image
  final Rect cropRect = state.getCropRect();

  var data = state.rawImageData;
  • prepare crop option
  final rotateAngle = action.rotateAngle.toInt();
  final flipHorizontal = action.flipY;
  final flipVertical = action.flipX;
  final img = state.rawImageData;

  ImageEditorOption option = ImageEditorOption();

  if (action.needCrop) option.addOption(ClipOption.fromRect(rect));

  if (action.needFlip)
    option.addOption(
        FlipOption(horizontal: flipHorizontal, vertical: flipVertical));

  if (action.hasRotateAngle) option.addOption(RotateOption(rotateAngle));
  • crop with editImage

output is raw image data, you can use it to save or any other thing.

  final result = await ImageEditor.editImage(
    image: img,
    imageEditorOption: option,
  );

more detail

Photo View

ExtendedImageGesturePageView is the same as PageView and it's made for show zoom/pan image.

if you have cache the gesture, remember call clearGestureDetailsCache() method at the right time.(for example,page view page is disposed)

img

ExtendedImageGesturePageView

parameter description default
cacheGesture whether should move page true

GestureConfig

parameter description default
cacheGesture save Gesture state (for example in ExtendedImageGesturePageView, gesture state will not change when scroll back),remember clearGestureDetailsCache at right time false
inPageView whether in ExtendedImageGesturePageView false
ExtendedImageGesturePageView.builder(
  itemBuilder: (BuildContext context, int index) {
    var item = widget.pics[index].picUrl;
    Widget image = ExtendedImage.network(
      item,
      fit: BoxFit.contain,
      mode: ExtendedImageMode.gesture,
      gestureConfig: GestureConfig(
        inPageView: true, initialScale: 1.0,
        //you can cache gesture state even though page view page change.
        //remember call clearGestureDetailsCache() method at the right time.(for example,this page dispose)
        cacheGesture: false
      ),
    );
    image = Container(
      child: image,
      padding: EdgeInsets.all(5.0),
    );
    if (index == currentIndex) {
      return Hero(
        tag: item + index.toString(),
        child: image,
      );
    } else {
      return image;
    }
  },
  itemCount: widget.pics.length,
  onPageChanged: (int index) {
    currentIndex = index;
    rebuild.add(index);
  },
  controller: PageController(
    initialPage: currentIndex,
  ),
  scrollDirection: Axis.horizontal,
),

Slide Out Page

Extended Image support to slide out page as WeChat.

img

enable slide out page

ExtendedImage

parameter description default
enableSlideOutPage whether enable slide out page false
heroBuilderForSlidingPage build Hero only for sliding page, the transform of sliding page must be working on Hero,so that Hero animation wouldn't be strange when pop page null

include your page in ExtendedImageSlidePage

take care of onSlidingPage call back, you can update other widgets' state as you want. but, do not setState directly here, image state will changed, you should only notify the widgets which are needed to change

    return ExtendedImageSlidePage(
      child: result,
      slideAxis: SlideAxis.both,
      slideType: SlideType.onlyImage,
      onSlidingPage: (state) {
        ///you can change other widgets' state on page as you want
        ///base on offset/isSliding etc
        //var offset= state.offset;
        var showSwiper = !state.isSliding;
        if (showSwiper != _showSwiper) {
          // do not setState directly here, the image state will change,
          // you should only notify the widgets which are needed to change
          // setState(() {
          // _showSwiper = showSwiper;
          // });

          _showSwiper = showSwiper;
          rebuildSwiper.add(_showSwiper);
        }
      },
    );

ExtendedImageGesturePage

parameter description default
child The [child] contained by the ExtendedImageGesturePage. -
slidePageBackgroundHandler build background when slide page defaultSlidePageBackgroundHandler
slideScaleHandler customize scale of page when slide page defaultSlideScaleHandler
slideEndHandler call back of slide end,decide whether pop page defaultSlideEndHandler
slideAxis axis of slide(both,horizontal,vertical) SlideAxis.both
resetPageDuration reset page position when slide end(not pop page) milliseconds: 500
slideType slide whole page or only image SlideType.onlyImage
onSlidingPage call back when it's sliding page, change other widgets state on page as you want -
slideOffsetHandler customize offset when slide page -
Color defaultSlidePageBackgroundHandler(
    {Offset offset, Size pageSize, Color color, SlideAxis pageGestureAxis}) {
  double opacity = 0.0;
  if (pageGestureAxis == SlideAxis.both) {
    opacity = offset.distance /
        (Offset(pageSize.width, pageSize.height).distance / 2.0);
  } else if (pageGestureAxis == SlideAxis.horizontal) {
    opacity = offset.dx.abs() / (pageSize.width / 2.0);
  } else if (pageGestureAxis == SlideAxis.vertical) {
    opacity = offset.dy.abs() / (pageSize.height / 2.0);
  }
  return color.withOpacity(min(1.0, max(1.0 - opacity, 0.0)));
}

bool defaultSlideEndHandler(
    {Offset offset, Size pageSize, SlideAxis pageGestureAxis}) {
  if (pageGestureAxis == SlideAxis.both) {
    return offset.distance >
        Offset(pageSize.width, pageSize.height).distance / 3.5;
  } else if (pageGestureAxis == SlideAxis.horizontal) {
    return offset.dx.abs() > pageSize.width / 3.5;
  } else if (pageGestureAxis == SlideAxis.vertical) {
    return offset.dy.abs() > pageSize.height / 3.5;
  }
  return true;
}

double defaultSlideScaleHandler(
    {Offset offset, Size pageSize, SlideAxis pageGestureAxis}) {
  double scale = 0.0;
  if (pageGestureAxis == SlideAxis.both) {
    scale = offset.distance / Offset(pageSize.width, pageSize.height).distance;
  } else if (pageGestureAxis == SlideAxis.horizontal) {
    scale = offset.dx.abs() / (pageSize.width / 2.0);
  } else if (pageGestureAxis == SlideAxis.vertical) {
    scale = offset.dy.abs() / (pageSize.height / 2.0);
  }
  return max(1.0 - scale, 0.8);
}

make sure your page background is transparent

if you use ExtendedImageSlidePage and slideType =SlideType.onlyImage, make sure your page background is transparent

push with transparent page route

you should push page with TransparentMaterialPageRoute/TransparentCupertinoPageRoute

  Navigator.push(
    context,
    Platform.isAndroid
        ? TransparentMaterialPageRoute(builder: (_) => page)
        : TransparentCupertinoPageRoute(builder: (_) => page),
  );

Slide Out Page Demo Code 1

Slide Out Page Demo Code 2

Border BorderRadius Shape

ExtendedImage

parameter description default
border BoxShape.circle and BoxShape.rectangle,If this is [BoxShape.circle] then [borderRadius] is ignored. -
borderRadius If non-null, the corners of this box are rounded by this [BorderRadius].,Applies only to boxes with rectangular shapes; ignored if [shape] is not [BoxShape.rectangle]. -
shape BoxShape.circle and BoxShape.rectangle,If this is [BoxShape.circle] then [borderRadius] is ignored. -
ExtendedImage.network(
  url,
  width: ScreenUtil.instance.setWidth(400),
  height: ScreenUtil.instance.setWidth(400),
  fit: BoxFit.fill,
  cache: true,
  border: Border.all(color: Colors.red, width: 1.0),
  shape: boxShape,
  borderRadius: BorderRadius.all(Radius.circular(30.0)),
),

img

Clear Save

clear

to clear disk cached , call clearDiskCachedImages method.

// Clear the disk cache directory then return if it succeed.
///  <param name="duration">timespan to compute whether file has expired or not</param>
Future<bool> clearDiskCachedImages({Duration duration})

to clear disk cached with specific url, call clearDiskCachedImage method.

/// clear the disk cache image then return if it succeed.
///  <param name="url">clear specific one</param>
Future<bool> clearDiskCachedImage(String url) async {

get the local cached image file

Future<File> getCachedImageFile(String url) async {

to clear memory cache , call clearMemoryImageCache method.

///clear all of image in memory
 clearMemoryImageCache();

/// get ImageCache
 getMemoryImageCache() ;

save network

call saveNetworkImageToPhoto and save image with image_picker_saver

///save network image to photo
Future<bool> saveNetworkImageToPhoto(String url, {bool useCache: true}) async {
  var data = await getNetworkImageData(url, useCache: useCache);
  var filePath = await ImagePickerSaver.saveFile(fileData: data);
  return filePath != null && filePath != "";
}

Show Crop Image

get your raw image by [Load State](#Load State), and crop image by sourceRect.

ExtendedRawImage sourceRect is which you want to show image rect.

img

ExtendedRawImage(
  image: image,
  width: num400,
  height: num300,
  fit: BoxFit.fill,
  sourceRect: Rect.fromLTWH(
      (image.width - width) / 2.0, 0.0, width, image.height.toDouble()),
)

Paint

provide BeforePaintImage and AfterPaintImage callback, you will have the chance to paint things you want.

img

ExtendedImage

parameter description default
beforePaintImage you can paint anything if you want before paint image. -
afterPaintImage you can paint anything if you want after paint image. -
  ExtendedImage.network(
    url,
    width: ScreenUtil.instance.setWidth(400),
    height: ScreenUtil.instance.setWidth(400),
    fit: BoxFit.fill,
    cache: true,
    beforePaintImage: (Canvas canvas, Rect rect, ui.Image image) {
      if (paintType == PaintType.ClipHeart) {
        if (!rect.isEmpty) {
          canvas.save();
          canvas.clipPath(clipheart(rect, canvas));
        }
      }
      return false;
    },
    afterPaintImage: (Canvas canvas, Rect rect, ui.Image image) {
      if (paintType == PaintType.ClipHeart) {
        if (!rect.isEmpty) canvas.restore();
      } else if (paintType == PaintType.PaintHeart) {
        canvas.drawPath(
            clipheart(rect, canvas),
            Paint()
              ..colorFilter =
                  ColorFilter.mode(Color(0x55ea5504), BlendMode.srcIn)
              ..isAntiAlias = false
              ..filterQuality = FilterQuality.low);
      }
    },
  );

see paint image demo and push to refresh header which is used in crop image demo

Notch

By setting layoutInsets, you can ensure the image is positioned outside of obstructing elements such as the phone notch or home indicator if displayed in full screen. This will still allow the image margin to show underneath the notch if zoomed in.

ExtendedImage

parameter description default
layoutInsets Amount to inset from the edge during image layout EdgeInsets.zero
  ExtendedImage.network(
    url,
    fit: BoxFit.contain,
    layoutInsets: MediaQuery.of(context).padding
  );

MemoryUsage

You can reduce memory usage with following settings now.

  • ExtendedResizeImage
parameter description default
[ExtendedResizeImage.compressionRatio] The images size will resize to original * [compressionRatio].It's ExtendedResizeImages first pick.The compressionRatio`s range is from 0.0 (exclusive), to 1.0 (exclusive). null
[ExtendedResizeImage.maxBytes] [ExtendedResizeImage] will compress the image to a size that is smaller than [maxBytes]. The default size is 50KB. It's actual bytes of Image, not decode bytes 50 << 10
[ExtendedResizeImage.width]/[ExtendedResizeImage.height] The width/height the image should decode to and cache. It's same as [ResizeImage], null
    ExtendedImage.network(
      'imageUrl',  
      compressionRatio: 0.1,
      maxBytes: null,
      cacheWidth: null,
      cacheHeight: null,  
    )

    ExtendedImage(
      image: ExtendedResizeImage(
        ExtendedNetworkImageProvider(
          'imageUrl',  
        ),
        compressionRatio: 0.1,
        maxBytes: null,
        width: null,
        height: null,
      ),
    )
  • clearMemoryCacheWhenDispose
parameter description default
clearMemoryCacheWhenDispose It's not good enough after Flutter 2.0, it seems that we can't release memory usage if this image is not completed(#317). It will release memory usage only for completed image now. false
   ExtendedImage.network(
     'imageUrl',     
     clearMemoryCacheWhenDispose: true,
   )
  • imageCacheName
parameter description default
imageCacheName The name of [ImageCache], you can define custom [ImageCache] to store this image. In this way you can work with them without affecting other [ImageCache] null
   ExtendedImage.network(
     'imageUrl',  
     imageCacheName: 'MemoryUsage',
   )
     
  /// clear when this page is disposed   
  @override
  void dispose() {
    // clear ImageCache which named 'MemoryUsage'
    clearMemoryImageCache(imageCacheName);
    super.dispose();
  }   

Other APIs

ExtendedImage

parameter description default
enableMemoryCache whether cache in PaintingBinding.instance.imageCache) true
clearMemoryCacheIfFailed when failed to load image, whether clear memory cache.if true, image will reload in next time. true
clearMemoryCacheWhenDispose when image is removed from the tree permanently, whether clear memory cache. false

More Repositories

1

wechat_flutter

wechat_flutter is Flutter version WeChat, an excellent Flutter instant messaging IM open source library!
Dart
2,512
star
2

NeteaseCloudMusic

Flutter - NeteaseCloudMusic Flutter 版本的网易云音乐
Dart
1,756
star
3

flutter_wechat_assets_picker

An image picker (also with video and audio) for Flutter projects based on the WeChat's UI.
Dart
1,500
star
4

flutter_smart_dialog

An elegant Flutter Dialog solution | 一种更优雅的 Flutter Dialog 解决方案
Dart
1,109
star
5

flutter_candies

custom flutter candies(widgets) for you to build flutter app easily, enjoy it
793
star
6

flutter_photo_manager

A Flutter plugin that provides images, videos, and audio abstraction management APIs without interface integration, available on Android, iOS, macOS and OpenHarmony.
Dart
675
star
7

extended_text

A powerful extended official text for Flutter, which supports Speical Text(Image,@somebody), Custom Background, Custom overFlow, Text Selection.
Dart
650
star
8

flutter_image_compress

flutter image compress
Dart
638
star
9

extended_nested_scroll_view

extended nested scroll view to fix following issues. 1.pinned sliver header issue 2.inner scrollables in tabview sync issue 3.pull to refresh is not work. 4.do without ScrollController in NestedScrollView's body
Dart
595
star
10

extended_text_field

extended official text field to quickly build special text like inline image, @somebody, custom background etc.
Dart
573
star
11

FlutterJsonBeanFactory

What I do is generate dart beans based on json, as well as generics parameters and json build instances
Kotlin
567
star
12

flutter_custom_calendar

Flutter的一个日历控件
Dart
501
star
13

like_button

Like Button is a flutter library that allows you to create a button with animation effects similar to Twitter's heart when you like something and animation effects to increase like count.
Dart
466
star
14

flutter_scrollview_observer

A widget for observing data related to the child widgets being displayed in a ScrollView. Maintainer: @LinXunFeng
Dart
427
star
15

flutter_image_editor

Flutter plugin, support android/ios.Support crop, flip, rotate, color martix, mix image, add text. merge multi images.
Dart
410
star
16

flutter_wechat_camera_picker

A camera picker (take photos and videos) for Flutter projects based on WeChat's UI. It's a standalone module of wechat_assets_picker yet it can be run separately.
Dart
364
star
17

loading_more_list

A loading more list which supports ListView,GridView,WaterfallFlow and Slivers.
Dart
361
star
18

waterfall_flow

A Flutter grid view which supports waterfall flow layout.
Dart
358
star
19

JsonToDart

The tool to convert json to dart code, support Windows,Mac,Web.
Dart
356
star
20

extended_tabs

A powerful official extension library of Tab/TabBar/TabView, which support to scroll ancestor or child Tabs when current is overscroll, and set scroll direction and cache extent.
Dart
267
star
21

ncov_2019

An online query App for COVID-19 statistics developed by Flutter was used.
Dart
255
star
22

flutter-interactive-chart

A candlestick chart that supports pinch-to-zoom and panning.
Dart
210
star
23

pull_to_refresh_notification

Flutter plugin for building pull to refresh effects with PullToRefreshNotification and PullToRefreshContainer quickly.
Dart
187
star
24

flutter_drawing_board

A new Flutter package of drawing board
Dart
180
star
25

extended_sliver

A powerful extension library of Sliver, which include SliverToNestedScrollBoxAdapter, SliverPinnedPersistentHeader, SliverPinnedToBoxAdapter and ExtendedSliverAppbar.
Dart
166
star
26

flutter_interactional_widget

Dart
163
star
27

extended_image_library

package library for extended_image, extended_text and extended_text_field,provide common base class.
Dart
154
star
28

flutter_tilt

👀 Easily apply tilt parallax hover effects for Flutter, which supports tilt, light, shadow effects, and gyroscope sensors | 为 Flutter 轻松创建倾斜视差悬停效果,支持倾斜、光照、阴影效果和陀螺仪传感器
Dart
144
star
29

ff_annotation_route

Provide route generator to create route map quickly by annotations.
Dart
122
star
30

flutter_filereader

Flutter实现的本地文件(pdf word excel 等)查看插件,非在线预览
Dart
109
star
31

nav_router

flutter The lightest, easiest and most convenient route management!
Dart
103
star
32

w_popup_menu

w_popup_menu # A pop-up menu that mimics the iOS WeChat page
Dart
89
star
33

flutter_asset_generator

Generate an R file for mapping all assets. Supports preview of image.
Dart
86
star
34

stack_board

层叠控件摆放
Dart
85
star
35

left-scroll-actions

Flutter的左滑删除组件
Dart
82
star
36

extended_text_library

extended_text_library for extended_text and extended_text_field
Dart
75
star
37

flutter_hsvcolor_picker

An HSV color picker designed for your Flutter app. Pickers: RGB, HSV, Color Wheel, Palette Hue, Palette Saturation, Palette Value, Swatches.
Dart
71
star
38

flex_grid

The FlexGrid control provides a powerful and quickly way to display data in a tabular format. It is including that frozened column/row,loading more, high performance and better experience in TabBarView/PageView.
Dart
60
star
39

no-free-usage-action

A NO-FREE-USAGE action for github. (Only worked with github action.)
Dart
60
star
40

extended_list

extended list(ListView/GridView) support track collect garbage of children/viewport indexes, build lastChild as special child in the case that it is loadmore/no more item and enable to layout close to trailing.
Dart
51
star
41

fconsole

一个用于调试的面板
Dart
50
star
42

flutter_juejin

https://juejin.cn in Flutter
Dart
48
star
43

gitcandies

A GitHub Flutter application.
Dart
47
star
44

flutter_ali_auth

Flutter Ali Auth Plugin 阿里云一键登录Flutter插件
Java
47
star
45

ripple_backdrop_animate_route

A ripple animation with backdrop of route.
Dart
45
star
46

flutter_apodidae

🔥🔥 收录 Flutter 优化合集,apodidae (雨燕)是飞翔速度最快的鸟类,与 flutter (颤动)不谋而合。
40
star
47

flutter_bdface_collect

a baidu face offline collect plugin. Only Android and IOS platforms are supported. 百度人脸离线采集插件,只支持安卓和iOS。
Objective-C
38
star
48

flutter_record_mp3

flutter record mp3 using the native api
Dart
34
star
49

assets_generator

The flutter tool to generate assets‘s configs(yaml) and consts automatically for single project and multiple modules.
Dart
34
star
50

flutter_qweather

和风天气 Flutter 插件
Dart
29
star
51

flutter_draggable_container

A Draggable Widget Container
Dart
28
star
52

baidupan

Baidu net disk api for dart, 百度网盘的 dart 库
Dart
28
star
53

flutter_switch_clipper

A Flutter package that two widgets switch with clipper.
Dart
26
star
54

dash_painter

a package for flutter canvas paint dash line path easily.
Dart
25
star
55

http_client_helper

A Flutter plugin for http request with cancel and retry fuctions.
Dart
25
star
56

flutter_live_activities

Flutter Live Activities Plugin
Dart
23
star
57

flutter_slider_view

A slider view widget that supports custom type models and various configs.
Dart
22
star
58

packages

Custom Flutter Candies (packages) for you to easily build your Flutter app. Enjoy it!
20
star
59

extra_hittest_area

Manually add the extra hitTest area of a widget without changing its size or layout.
Dart
18
star
60

flutter_learning_tests

学习 Flutter 路上的点滴及小测~
Dart
17
star
61

ios_willpop_transition_theme

A Flutter package to solve the conflict between ios sliding back and Willpop
Dart
17
star
62

saver_gallery

Kotlin
15
star
63

flutter_mlkit_scan_plugin

Kotlin
15
star
64

should_rebuild

Dart
14
star
65

candies_analyzer_plugin

The plugin to help create custom analyzer plugin quickly and provide some useful lints and get suggestion and auto import for extension member.
Dart
14
star
66

flutter_novel

一款开源免费的在线小说阅读app,使用flutter进行开发
Dart
13
star
67

flutter_candies_gallery

flutter_candies
Dart
12
star
68

scan_barcode

Barcode/QRCode scan, base of google mikit.
Dart
12
star
69

CandiesBot

Java
11
star
70

flutter_float_window

flutter_float_window是一个悬浮窗插件,具备悬浮窗权限申请等功能
Java
11
star
71

extended_list_library

package library for extended_list and waterfall_flow, it provides core classes.
Dart
10
star
72

photo_widget

Base on photo_manager, wraps up some UI components to quickly display the photo_manager as a usable widget, inserting it wherever you need it.
Dart
10
star
73

extended_keyboard

Flutter plugin for create custom keyboards quickly.
Dart
10
star
74

flutter_app_build_tool

A CLI tool that helps to build Flutter apps.
Dart
9
star
75

douget

Dart
9
star
76

coordtransform

A coord transform tool. 提供百度坐标系(BD-09)、火星坐标系(国测局坐标系、GCJ02)、WGS84坐标系的相互转换。
Dart
9
star
77

ff_native_screenshot

A Flutter plugin to take or listen screenshot(support Platform Views) for Android and iOS with native code.
Java
9
star
78

flutter_custom_inspector

A customizable inspector that can called directly through Flutter apps.
Dart
8
star
79

adaptation

Screen for adaptation.
C++
8
star
80

properties

Load properties format in dart or flutter
Dart
7
star
81

w_reorder_list

Dart
7
star
82

JsonToDartWeb

JsonToDart Web 带字体文件
7
star
83

flutter_candies_demo_library

package library for demo of flutter candies, it provides core classes.
Dart
7
star
84

sync_scroll_library

The library for extended_tabs and flex_grid
Dart
6
star
85

env2dart

A simple way to generate `dart` code from a `.env` file.
Dart
6
star
86

loading_more_list_library

dart package library for LoadingMoreList, it provides core classes.
Dart
6
star
87

ff_annotation_route_library

The library for ff_annotation_route
Dart
5
star
88

dext

Some extension for dart
Dart
5
star
89

flutter_clean

help clean all of Flutter and Dart projects
Dart
4
star
90

flutter_challenges

Just do the first one, don't do second who.
Dart
4
star
91

flutter_candies_package_tools

tool to create package and demo
Dart
4
star
92

simple_provider

flutter simple provider
Dart
3
star
93

upgrade_tool

Resolve warnings caused by xxxbinding. Instance in Flutter 3.0
Dart
3
star
94

note_edit

A library of flutter note editor plugins.
Dart
2
star
95

blue_flutter

blue_flutter是flutter的蓝牙通讯插件
Java
2
star
96

ff_annotation_route_core

The core library for ff_annotation_route
Dart
2
star
97

mvimg

For get video from motion photo for android.
Dart
2
star
98

dart_wake_on_lan

A CLI application to send Wake-On-Lan packets.
Dart
2
star
99

.github

2
star
100

maven

Organizational maven deploy;组织的maven仓库;
1
star