Git Product home page Git Product logo

octo_image's Introduction

OctoImage

pub package Build Status codecov

An image library for showing placeholders, error widgets and transform your image.

Recommended using with CachedNetworkImage version 2.2.0 or newer.

Getting Started

The OctoImage widget needs an ImageProvider to show the image. You can either supply the widget with a placeholder or progress indicator, an ImageBuilder and/or an error widget.

However, what OctoImage makes is the use of OctoSets. OctoSets are predefined combinations of placeholders, imagebuilders and error widgets.

So, either set the all the components yourself:

OctoImage(
  image: CachedNetworkImageProvider(
      'https://blurha.sh/assets/images/img1.jpg'),
  placeholderBuilder: OctoPlaceholder.blurHash(
    'LEHV6nWB2yk8pyo0adR*.7kCMdnj',
  ),
  errorBuilder: OctoError.icon(color: Colors.red),
  fit: BoxFit.cover,
);

Or use an OctoSet:

OctoImage.fromSet(
  fit: BoxFit.cover,
  image: CachedNetworkImageProvider(
    'https://upload.wikimedia.org/wikipedia/commons/thumb/4/4e/Macaca_nigra_self-portrait_large.jpg/1024px-Macaca_nigra_self-portrait_large.jpg',
  ),
  octoSet: OctoSet.circleAvatar(
    backgroundColor: Colors.red,
    text: Text("M"),
  ),
);

The CircleAvatar set shows a colored circle with the text inside during loading and when the image failed loading. When the image loads it animates to the image clipped as a circle.

ImageProviders

The recommended one is CachedNetworkImageProvider, as that supports the progress indicator, error and caching. It also works on Android, iOS, web and macOS, although without caching on the web. Make sure you use at least version 2.2.0.

The second best is NetworkImage, but any ImageProvider works in theory. However, for some ImageProviders (such as MemoryImage) it doesn't make sense to use OctoImage.

Placeholders and progress indicators

It would be best if you used either a placeholder or a progress indicator, but not both. Placeholders are only building once the image starts loading, but progress indicators are rebuilt every time new progress information is received. So if you don't use that progress indication, for example, with a static image, you should use a placeholder.

The most simple progress indicators use a CircularProgressIndicator.

OctoImage(
  image: image,
  progressIndicatorBuilder: (context) => 
    const CircularProgressIndicator(),
),
OctoImage(
  image: image,
  progressIndicatorBuilder: (context, progress) {
    double value;
    if (progress != null && progress.expectedTotalBytes != null) {
      value =
          progress.cumulativeBytesLoaded / progress.expectedTotalBytes;
    }
    return CircularProgressIndicator(value: value);
  },
),

However, because these are used so often, we prebuild these widgets for you. Just use OctoProgressIndicator.circularProgressIndicator()

OctoImage(
  image: image,
  progressIndicatorBuilder: OctoProgressIndicator.circularProgressIndicator(),
),

All included placeholders and progress indicators:

OctoPlaceholder Explanation
blurHash Shows a BlurHash image
circleAvatar Shows a colored circle with a text
circularProgressIndicator Shows a circularProgressIndicator with indeterminate progress.
frame Shows the Flutter Placeholder
OctoProgressIndicator Explanation
circularProgressIndicator Shows a simple CircularProgressIndicator

Error widgets

Error widgets are shown when the ImageProvider throws an error because the image failed loading. You can build a custom widget, or use the prebuild widgets:

OctoImage(
  image: image,
  errorBuilder: (context, error, stacktrace) =>
    const Icon(Icons.error),
);
OctoImage(
  image: image,
  errorBuilder: OctoError.icon(),
),

All included error widgets are:

OctoError Explanation
blurHash Shows a BlurHash placeholder with an error icon.
circleAvatar Shows a colored circle with a text
icon Shows an icon, default to Icons.error
placeholderWithErrorIcon Shows any placeholder with an icon op top.

Image builders

Image builders can be used to adapt the image before it is shown. For example the circleAvatar clips the image in a circle, but you could also add an overlay or anything else.

The builder function supplies a context and a child. The child is the image widget that is rendered.

An example that shows the image with 50% opacity:

OctoImage(
  image: image,
  imageBuilder: (context, child) => Opacity(
    opacity: 0.5,
    child: child,
  ),
),

A prebuild image transformer that clips the image as a circle:

OctoImage(
  image: image,
  imageBuilder: OctoImageTransformer.circleAvatar(),
),

All included image transformers are:

OctoImageTransformer Explanation
circleAvatar Clips the image in a circle

OctoSets

You get the most out of OctoImage when you use OctoSets. These sets contain a combination of a placeholder or progress indicator, an image builder and/or an error widget builder. It always contains at least a placeholder or progress indicator and an error widget.

You can use them with OctoImage.fromSet:

OctoImage.fromSet(
  image: image,
  octoSet: OctoSet.circleAvatar(backgroundColor: Colors.red, text: Text("M")),
),

All included OctoSets are:

OctoSet Explanation
circleAvatar Shows a colored circle with text during load and error. Clips the image after successful load.
circularIndicatorAndIcon Shows a circularProgressIndicator with or without progress and an icon on error.

Blurhash

You can easily create your own OctoSet though, for example if you want to use blurHash as a placeholder:

/// Simple set to show [OctoPlaceholder.circularProgressIndicator] as
/// placeholder and [OctoError.icon] as error.
OctoSet blurHash(
  String hash, {
  BoxFit? fit,
  Text? errorMessage,
}) {
  return OctoSet(
    placeholderBuilder: blurHashPlaceholderBuilder(hash, fit: fit),
    errorBuilder: blurHashErrorBuilder(hash, fit: fit),
  );
}

OctoPlaceholderBuilder blurHashPlaceholderBuilder(String hash, {BoxFit? fit}) {
  return (context) => SizedBox.expand(
    child: Image(
      image: BlurHashImage(hash),
      fit: fit ?? BoxFit.cover,
    ),
  );
}


OctoErrorBuilder blurHashErrorBuilder(
  String hash, {
  BoxFit? fit,
  Text? message,
  IconData? icon,
  Color? iconColor,
  double? iconSize,
}) {
  return OctoError.placeholderWithErrorIcon(
    blurHashPlaceholderBuilder(hash, fit: fit),
    message: message,
    icon: icon,
    iconColor: iconColor,
    iconSize: iconSize,
  );
}

Contribute

If you would like to contribute to the plugin (e.g. by improving the documentation, solving a bug or adding a cool new feature), please carefully review our contribution guide and send us your pull request.

PR's with any new prebuild widgets or sets are highly appreciated.

Support

  • Feel free to open an issue. Make sure to use one of the templates!
  • Commercial support is available. Integration with your app or services, samples, feature request, etc. Email: [email protected]
  • Powered by: baseflow.com

octo_image's People

Contributors

j-j-gajjar avatar koiralapankaj7 avatar martijn00 avatar rbt22 avatar renefloor avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

octo_image's Issues

[web] support for new CanvasKit

๐Ÿ› Bug Report

Using OctoImage with the new CanvasKit Skia support seems to result in

Another exception was thrown: Expected a value of type 'SkImage', but got one of type 'HtmlImage'

exceptions. I'm still investigating, just asking if you already tried it.

Size is infinite although width and or height are set.

๐Ÿ› Bug Report

Size is infinite although width and or height are set.

Expected behavior

I expect the widget to adhere to the width and height that are set.

Reproduction steps

Leading widget consumes entire tile width. Please use a sized widget.
'package:flutter/src/material/list_tile.dart':
Failed assertion: line 1353 pos 7: 'tileWidth != leadingSize.width'

I have the image inside a ListTile like this:

ListTile(
                      contentPadding: EdgeInsets.only(
                          left: 4.0, right: 8.0, top: 4.0, bottom: 4.0),
                      leading: CachedNetworkImage(
                        imageUrl:
                            "https://www.themealdb.com/images/ingredients/" +
                                Uri.encodeComponent(item.title) +
                                ".png",
                        placeholder: (context, url) =>
                            CircularProgressIndicator(),
                        errorWidget: (context, url, error) => Icon(Icons.error),
                        fit: BoxFit.fill,
                        width: 32,
                        height: 32,
                      ),
                      title: Text(item.title, style: Styles.listText),
                      trailing: Icon(Icons.add),
                      onTap: () {
                        Navigator.of(context).pop();
                      }),

From: Baseflow/flutter_cached_network_image#273 (comment)

Configuration

Version: 0.2.0

Platform:

  • ๐Ÿ“ฑ iOS
  • ๐Ÿค– Android

Update examples (blurhash)

It seems blurhash has been removed - but the first example in the documentation still showcases how to use it:

OctoImage(
  image: CachedNetworkImageProvider(
      'https://blurha.sh/assets/images/img1.jpg'),
  placeholderBuilder: OctoPlaceholder.blurHash(
    'LEHV6nWB2yk8pyo0adR*.7kCMdnj',
  ),
  errorBuilder: OctoError.icon(color: Colors.red),
  fit: BoxFit.cover,
);

Yet there is no OctoPlacholder.blurHash(...) method anymore. Please update the examples!

Errors and crashes on removed `OctoImage` widget

๐Ÿ› Bug Report

Error after removing image which result in crash if route with deleted image widget is popped
log.txt

Expected behavior

No errors

Reproduction steps

Delete image widget from list AutomaticAnimatedListView of library great_list_view
Error also can be reproduced with cached_network_image. DioImage implementation is copied from here because it depends on previous major version of dio

Configuration

Version: 1.0.2

flutter doctor -v

    โ€ข Flutter version 3.7.3 on channel stable at /Users/vovchara/Documents/flutter
    โ€ข Upstream repository https://github.com/flutter/flutter.git
    โ€ข Framework revision 9944297138 (10 days ago), 2023-02-08 15:46:04 -0800
    โ€ข Engine revision 248290d6d5
    โ€ข Dart version 2.19.2
    โ€ข DevTools version 2.20.1

[โœ“] Android toolchain - develop for Android devices (Android SDK version 33.0.0)
    โ€ข Android SDK at /Users/vovchara/Library/Android/sdk
    โ€ข Platform android-33, build-tools 33.0.0
    โ€ข Java binary at: /Applications/Android Studio.app/Contents/jre/Contents/Home/bin/java
    โ€ข Java version OpenJDK Runtime Environment (build 11.0.13+0-b1751.21-8125866)
    โ€ข All Android licenses accepted.

[โœ“] Xcode - develop for iOS and macOS (Xcode 14.2)
    โ€ข Xcode at /Applications/Xcode.app/Contents/Developer
    โ€ข Build 14C18
    โ€ข CocoaPods version 1.11.3

[โœ“] Chrome - develop for the web
    โ€ข Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome

[โœ“] Android Studio (version 2021.3)
    โ€ข Android Studio at /Applications/Android Studio.app/Contents
    โ€ข Flutter plugin can be installed from:
      ๐Ÿ”จ https://plugins.jetbrains.com/plugin/9212-flutter
    โ€ข Dart plugin can be installed from:
      ๐Ÿ”จ https://plugins.jetbrains.com/plugin/6351-dart
    โ€ข Java version OpenJDK Runtime Environment (build 11.0.13+0-b1751.21-8125866)

[โœ“] VS Code (version 1.75.1)
    โ€ข VS Code at /Applications/Visual Studio Code.app/Contents
    โ€ข Flutter extension version 3.58.0

[โœ“] Connected device (2 available)
    โ€ข macOS (desktop) โ€ข macos  โ€ข darwin-arm64   โ€ข macOS 13.2.1 22D68 darwin-arm64
    โ€ข Chrome (web)    โ€ข chrome โ€ข web-javascript โ€ข Google Chrome 110.0.5481.100

[โœ“] HTTP Host Availability
    โ€ข All required HTTP hosts are available

โ€ข No issues found!

Platform:

  • MacOS 13.2.1

Memory leak and crash with gapless

I got an issue with OOM on a very low device with random crashes. After investigation, I figure out that the problem with ImageHandler was reassigned.

Why did it happen?
Because in _OctoImageState in didUpdateWidget method each time reassign previous handler and saves current as well because of placeholder + progressBuilder properties. So in time, you have a situation where during the build method code executes build for all prev handlers and request all the images in the hierarchy(for 12 images on screen after 1 min with 10-sec delay of changing URL have 60 sec/10 delay =6 requests for each image + decoding job which cause the crash).

Fix proposal
Instead of each time reassigning handler need to create a new handler for the previous state without a placeholder and progress from the current handle or provide a way how to clear prev handler

instead of
_previousHandler = _imageHandler;
Need to recreate ImageHandler without placeholder from current ImageHandler

_previousHandler = ImageHandler(
          image: oldWidget.image,
          imageBuilder: oldWidget.imageBuilder,
          placeholderBuilder: oldWidget.placeholderBuilder,
          progressIndicatorBuilder: oldWidget.progressIndicatorBuilder,
          errorBuilder: oldWidget.errorBuilder,
          placeholderFadeInDuration: oldWidget.placeholderFadeInDuration,
          fadeOutDuration: oldWidget.fadeOutDuration,
          fadeOutCurve: oldWidget.fadeOutCurve,
          fadeInDuration: oldWidget.fadeInDuration,
          fadeInCurve: oldWidget.fadeInCurve,
          fit: oldWidget.fit,
          width: oldWidget.width,
          height: oldWidget.height,
          alignment: oldWidget.alignment,
          repeat: oldWidget.repeat,
          color: oldWidget.color,
          colorBlendMode: oldWidget.colorBlendMode,
          matchTextDirection: oldWidget.matchTextDirection,
          filterQuality: oldWidget.filterQuality,
        );

This issue is not related to Flutter 3.x. It's reproducible on 2.10.3 and 3.x.

I also saw a couple of old issues with CachableImage on flutter GitHub, and I think that can be a root cause of crashes

reportError throws assertion: setState() called after dispose()

RESOLVED: Fixed in Flutter master branch on 18th of May 2020

getting below in logs with below example:

    return OctoImage(
      image: CachedNetworkImageProvider(url),
      placeholderBuilder: (context) =>
          context.watch<ThemeProvider>().isLightTheme
              ? CircularProgressIndicator(
                  backgroundColor: Theme.of(context).primaryColor,
                  valueColor: const AlwaysStoppedAnimation(Colors.white),
                )
              : CircularProgressIndicator(
                  backgroundColor: Theme.of(context).primaryColor,
                ),
      errorBuilder: (context, url, dynamic error) => _sizedContainer(
        Icon(
          Icons.error,
          color: Colors.red,
        ),
      ),
    );
โ•โ•โ•โ•โ•โ•โ•โ• Exception caught by image resource service โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•
The following assertion was thrown when reporting an error to an image listener:
setState() called after dispose(): _ImageState#8fa88(lifecycle state: defunct, not mounted, stream: ImageStream#ebcf8(MultiFrameImageStreamCompleter#209a4, [960ร—720] @ 1.0x, 1 listener), pixels: null, loadingProgress: null, frameNumber: null, wasSynchronouslyLoaded: false)

This error happens if you call setState() on a State object for a widget that no longer appears in the widget tree (e.g., whose parent widget no longer includes the widget in its build). This error can occur when code calls setState() from a timer or an animation callback.

The preferred solution is to cancel the timer or stop listening to the animation in the dispose() callback. Another solution is to check the "mounted" property of this object before calling setState() to ensure the object is still in the tree.
This error might indicate a memory leak if setState() is being called because another object is retaining a reference to this State object after it has been removed from the tree. To avoid memory leaks, consider breaking the reference to this object during dispose().

When the exception was thrown, this was the stack: 
#0      State.setState.<anonymous closure> (package:flutter/src/widgets/framework.dart:1197:9)
#1      State.setState (package:flutter/src/widgets/framework.dart:1232:6)
#2      _ImageState._getListener.<anonymous closure> (package:flutter/src/widgets/image.dart:1116:13)
#3      ImageStreamCompleter.reportError (package:flutter/src/painting/image_stream.dart:504:24)
#4      ImageStreamCompleter.setImage (package:flutter/src/painting/image_stream.dart:439:9)
...
โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•

โ•โ•โ•โ•โ•โ•โ•โ• Exception caught by image resource service โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•
setState() called after dispose(): _ImageState#b0bda(lifecycle state: defunct, not mounted, stream: ImageStream#6f11d(MultiFrameImageStreamCompleter#366d4, [1632ร—1224] @ 1.0x, 1 listener), pixels: null, loadingProgress: null, frameNumber: null, wasSynchronouslyLoaded: false)
โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•

Inkwell effect on image

I'm sure you are aware of the various problems with inkwell effects on images. What's your preferred solution with respect to Octoimage? Maybe could include an option to include the Image as Ink.Image rather than the normal Image(....)?

Or, as I mentioned in my separate request, provide the imageprovider in the imagebuilder constructor and allow the user to do this him/her-self?

Image decode complete notification

๐Ÿš€ Feature Requests

Due to some needs of the project, we need to monitor the loading time of pictures, not only downloading, including decoding. That is, we need to know how many times to display a set of pictures, from the begin loading to render complete (rendering monitoring may be difficult, then use the decoding completion time is ok) .

I think the property _isLoaded of ImageHandler is very useful, how to expose it. Actually, we want to use(or get) it in CachedNetworkImage

Contextualize the feature

Describe the feature

Platforms affected (mark all that apply)

  • ๐Ÿ“ฑ iOS
  • ๐Ÿค– Android

[Regression] BoxFit cover for placeholder and error builders

๐Ÿ”™ Regression

Old (and correct) behavior

When using Image.asset with BoxFit cover as placeholder or error builders, the fit is applied correctly. (On cached_network_image v2.2.0)

Current behavior

The specified BoxFit for the placeholder and error builders is not applied.

Reproduction steps

Simple example. In a real scenario the placeholder would be an Image.asset widget, but this is enough to see the regression.

Container(
    color: Colors.red,
    child: OctoImage(
      image: NetworkImage('...'),
      placeholderBuilder: (context) {
        return Image.network(
          "https://blurha.sh/assets/images/img1.jpg",
          fit: BoxFit.cover,
        );
      },
      errorBuilder: (context, e, s) {
        return Image.network(
          "https://blurha.sh/assets/images/img1.jpg",
          fit: BoxFit.cover,
        );
      },
      fit: BoxFit.cover,
      height: 100,
      width: 100,
    ),
  ),

image

Configuration

Version: 0.2.1

problem in The method 'blurHash' isn't defined for the type 'OctoPlaceholder'. Try correcting the name to the name of an existing method, or defining a method named 'blurHash'.dartundefined_method Type: InvalidType

import 'package:cached_network_image/cached_network_image.dart';
import 'package:flutter/material.dart';
import 'package:instagram/presentation/widgets/global/others/play_this_video.dart';
// ignore: depend_on_referenced_packages
import 'package:octo_image/octo_image.dart';

class NetworkDisplay extends StatefulWidget {
final int cachingHeight, cachingWidth;
final String url, blurHash;
final double aspectRatio;
final bool isThatImage;
final double? height;
final double? width;

const NetworkDisplay({
Key? key,
required this.url,
this.isThatImage = true,
this.cachingHeight = 720,
this.cachingWidth = 720,
this.height,
this.width,
this.blurHash = "",
this.aspectRatio = 0.0,
}) : super(key: key);

@OverRide
State createState() => _NetworkDisplayState();
}

class _NetworkDisplayState extends State {
@OverRide
void initState() {
super.initState();
}

@OverRide
void didChangeDependencies() {
if (widget.isThatImage && widget.url.isNotEmpty) {
precacheImage(NetworkImage(widget.url), context);
}
super.didChangeDependencies();
}

@OverRide
Widget build(BuildContext context) {
return widget.aspectRatio == 0 ? whichBuild(height: null) : aspectRatio();
}

Widget aspectRatio() {
return AspectRatio(
aspectRatio: widget.aspectRatio,
child: whichBuild(),
);
}

Widget whichBuild({double? height = double.infinity}) {
return !widget.isThatImage
? PlayThisVideo(
play: true,
videoUrl: widget.url,
blurHash: widget.blurHash,
)
: buildOcto(height);
}

Widget buildOcto(height) {
int cachingHeight = widget.cachingHeight;
int cachingWidth = widget.cachingWidth;
if (widget.aspectRatio != 1 && cachingHeight == 720) cachingHeight = 960;
return OctoImage(
image: CachedNetworkImageProvider(widget.url,
maxWidth: cachingWidth, maxHeight: cachingHeight),
errorBuilder: (context, url, error) => buildError(),
fit: BoxFit.cover,
width: widget.width ?? double.infinity,
height: widget.height ?? height,
placeholderBuilder: widget.blurHash.isNotEmpty
? OctoPlaceholder.blurHash(widget.blurHash, fit: BoxFit.cover)
: (context) => Center(child: loadingWidget()),
);
}

SizedBox buildError() {
return SizedBox(
width: double.infinity,
height: widget.aspectRatio,
child: Icon(Icons.warning_amber_rounded,
size: 30, color: Theme.of(context).focusColor),
);
}

Widget loadingWidget() {
double aspectRatio = widget.aspectRatio;
return aspectRatio == 0
? buildSizedBox()
: AspectRatio(
aspectRatio: aspectRatio,
child: buildSizedBox(),
);
}

Widget buildSizedBox() {
return Container(
width: double.infinity,
color: Theme.of(context).textTheme.bodyMedium!.color,
child: Center(
child: CircleAvatar(
radius: 57,
backgroundColor: Theme.of(context).textTheme.bodySmall!.color,
child: Center(
child: CircleAvatar(
radius: 56,
backgroundColor: Theme.of(context).textTheme.bodyMedium!.color,
)),
)),
);
}
}

How i can Solve this problem please

gaplessPlayback broken: Bad state: Cannot clone a disposed image.

๐Ÿ”™ Regression

@renefloor

Minimal reproducible sample with OctoImage(checked iOS only)

On the latest beta channel.
What is more interesting on 1.22.0-12.1.pre everything was fine.

import 'dart:async';

import 'package:flutter/material.dart';
import 'package:octo_image/octo_image.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  int index = 0;

  @override
  void initState() {
    super.initState();
    Timer.periodic(
      Duration(seconds: 2),
      (timer) {
        setState(() {
          ++index;
        });
      },
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: OctoImage(
        image:
            NetworkImage('https://via.placeholder.com/300.png/09f/fff?index=$index'),
        imageBuilder: (_, image) => image,
        placeholderBuilder: (_) => Container(color: Colors.red),
        gaplessPlayback: true,
      ),
    );
  }
}

[โœ“] Flutter (Channel beta, 1.26.0-17.6.pre, on macOS 11.2.1 20D75 darwin-x64, locale en)
โ€ข Flutter version 1.26.0-17.6.pre at /Users/yauhen_sampir/fvm/versions/beta
โ€ข Framework revision a29104a69b (9 days ago), 2021-02-16 09:26:56 -0800
โ€ข Engine revision 21fa8bb99e
โ€ข Dart version 2.12.0 (build 2.12.0-259.12.beta)

[โœ“] Android toolchain - develop for Android devices (Android SDK version 29.0.3)
โ€ข Android SDK at /Users/yauhen_sampir/Library/Android/sdk
โ€ข Platform android-30, build-tools 29.0.3
โ€ข Java binary at: /Applications/Android Studio.app/Contents/jre/jdk/Contents/Home/bin/java
โ€ข Java version OpenJDK Runtime Environment (build 1.8.0_242-release-1644-b3-6915495)
โ€ข All Android licenses accepted.

[โœ“] Xcode - develop for iOS and macOS
โ€ข Xcode at /Applications/Xcode.app/Contents/Developer
โ€ข Xcode 12.4, Build version 12D4e
โ€ข CocoaPods version 1.10.1

[โœ“] Chrome - develop for the web
โ€ข Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome

[โœ“] Android Studio (version 4.1)
โ€ข Android Studio at /Applications/Android Studio.app/Contents
โ€ข Flutter plugin can be installed from:
๐Ÿ”จ https://plugins.jetbrains.com/plugin/9212-flutter
โ€ข Dart plugin can be installed from:
๐Ÿ”จ https://plugins.jetbrains.com/plugin/6351-dart
โ€ข Java version OpenJDK Runtime Environment (build 1.8.0_242-release-1644-b3-6915495)

[โœ“] VS Code (version 1.53.2)
โ€ข VS Code at /Applications/Visual Studio Code.app/Contents
โ€ข Flutter extension version 3.9.0

Also can be reproduced using cached network image package
Baseflow/flutter_cached_network_image#513

extend OctoImage-->imageBuilder to also include the imageprovider

Great package!

Sometimes it is also valuable to obtain the imageprovider in the imageBuilder constructor.

Currently it looks like this:
typedef OctoImageBuilder = Widget Function(BuildContext context, Widget child);

Hence I'd like it changed to
typedef OctoImageBuilder = Widget Function(BuildContext context, Widget child, Imageprovider image);

Had a look at CachedNetworkImage, and did a workaround:

  ImageProvider imageProvider =...

   return OctoImage(
    image: imageProvider,
     ...
    imageBuilder: (context, _) => here i'm using the imageProvider
  );

but would be more slick to have the imageprovider directly in the imageBuilder's constructor

flutter master channel build failed

๐Ÿ› Bug Report

/C:/Users/sksso/AppData/Local/Pub/Cache/hosted/pub.dev/flutter_blurhash-0.7.0/lib/src/blurhash_widget.dart(218,42): error G5FE39F1E: Type 'DecoderCallback' not found. [E:\sksmarket\sksmarket\build\windows\flutter\flutter_assemble.vcxproj]

Expected behavior

Reproduction steps

Configuration

Version: 1.x

Platform:

  • ๐Ÿ“ฑ iOS
  • ๐Ÿค– Android

gaplessPlayback doesn't fade

๐Ÿš€ Feature Requests

Make gaplessPlayback fade from one image to the next

Contextualize the feature

OctoImage support nicely fading from placeholder to image, but it doesn't fade from one image to the next

Describe the feature

Make gaplessPlayback fade the image from one to the next just like the placeholder fades.

Platforms affected (mark all that apply)

  • ๐Ÿ“ฑ iOS
  • ๐Ÿค– Android

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.