Code Monkey home page Code Monkey logo

Comments (5)

olive009 avatar olive009 commented on May 20, 2024

I got this issue too, but it's OK if using normal FadeInImage.memoryNetwork()

from photo_view.

krwrang avatar krwrang commented on May 20, 2024

Ran into this as well.
Master page is basically StaggeredGridView -> GestureDetector -> Hero -> FadeInImage

GestureDetector opens detail view, that has:
Center -> Hero -> PhotoView -> NetworkImage
Detail view blinks when opening.

from photo_view.

olive009 avatar olive009 commented on May 20, 2024

one possible implementation:

import 'dart:async';
import 'package:flutter/material.dart';
import 'package:photo_view/photo_view_image_wrapper.dart';
import 'package:photo_view/photo_view_scale_boundaries.dart';
import 'package:photo_view/photo_view_scale_state.dart';
import 'package:photo_view/photo_view_utils.dart';
import 'package:after_layout/after_layout.dart';

export 'package:photo_view/photo_view_scale_boundary.dart';

class HeroPhotoView extends StatefulWidget {
  final ImageProvider imageProvider;
  final Widget loadingChild;
  final Color backgroundColor;
  final minScale;
  final maxScale;
  final bool gaplessPlayback;
  final Size size;

  HeroPhotoView({
    Key key,
    @required this.imageProvider,
    this.loadingChild,
    this.backgroundColor = const Color.fromRGBO(0, 0, 0, 1.0),
    this.minScale,
    this.maxScale,
    this.gaplessPlayback = false,
    this.size,
  }) : super(key: key);

  @override
  State<StatefulWidget> createState() {
    return new _HeroPhotoViewState();
  }
}

class _HeroPhotoViewState extends State<HeroPhotoView> {
  PhotoViewScaleState _scaleState;
  GlobalKey containerKey = new GlobalKey();
  ImageInfo _imageInfo;

  Future<ImageInfo> _getImage() {
    Completer completer = new Completer<ImageInfo>();
    ImageStream stream = widget.imageProvider.resolve(new ImageConfiguration());
    var listener = (ImageInfo info, bool completed) {
      completer.complete(info);
      setState(() {
        _imageInfo = info;
      });
    };
    stream.addListener(listener);
    completer.future.then((_) {
      stream.removeListener(listener);
    });
    return completer.future;
  }

  void onDoubleTap() {
    setState(() {
      _scaleState = nextScaleState(_scaleState);
    });
  }

  void onStartPanning() {
    setState(() {
      _scaleState = PhotoViewScaleState.zooming;
    });
  }

  @override
  void initState() {
    _getImage();
    super.initState();
    _scaleState = PhotoViewScaleState.contained;
  }

  @override
  Widget build(BuildContext context) {
    if (_imageInfo == null) {
      return new SizedBox();
    }
    return new PhotoViewImageWrapper(
      onDoubleTap: onDoubleTap,
      onStartPanning: onStartPanning,
      imageProvider: widget.imageProvider,
      imageInfo: _imageInfo,
      scaleState: _scaleState,
      backgroundColor: widget.backgroundColor,
      gaplessPlayback: widget.gaplessPlayback,
      size: widget.size ?? MediaQuery.of(context).size,
      scaleBoundaries: new ScaleBoundaries(
        widget.minScale ?? 0.0,
        widget.maxScale ?? 100000000000.0,
        imageInfo: _imageInfo,
        size: widget.size ?? MediaQuery.of(context).size,
      ),
    );
  }

  Widget buildLoading() {
    return widget.loadingChild != null
        ? widget.loadingChild
        : new Center(
            child: new Text(
            "Loading",
            style: new TextStyle(color: Colors.white),
          ));
  }
}

class PhotoViewInline extends StatefulWidget {
  final ImageProvider imageProvider;
  final Widget loadingChild;
  final Color backgroundColor;
  final minScale;
  final maxScale;

  PhotoViewInline({
    Key key,
    @required this.imageProvider,
    this.loadingChild,
    this.backgroundColor = const Color.fromRGBO(0, 0, 0, 1.0),
    this.minScale,
    this.maxScale,
  }) : super(key: key);

  @override
  State<StatefulWidget> createState() => new _PhotoViewInlineState();
}

class _PhotoViewInlineState extends State<PhotoViewInline>
    with AfterLayoutMixin<PhotoViewInline> {
  Size _size;

  @override
  void afterFirstLayout(BuildContext context) {
    setState(() {
      _size = context.size;
    });
  }

  @override
  Widget build(BuildContext context) {
    return new HeroPhotoView(
      imageProvider: widget.imageProvider,
      loadingChild: widget.loadingChild,
      backgroundColor: widget.backgroundColor,
      minScale: widget.minScale,
      maxScale: widget.maxScale,
      size: _size,
    );
  }
}

from photo_view.

renancaraujo avatar renancaraujo commented on May 20, 2024

Thanks for reporting this, I will look into that in the next few days.
@olive009 Feel free to open a PR with your solution, this way we can collaborate more easily 😊.

from photo_view.

renancaraujo avatar renancaraujo commented on May 20, 2024

Adding another Photo view variant class as suggested by @olive009 in #19 would increase the complexity when using the Photo View API (ie: what if photoViewinline with hero?). In #22 I've added another option to PhotoView constructor: heroTag.

Now, to achieve the hero effect, do not put PhotoView as a child of a Hero. Instead, inform a heroTag as a param.
Example of usage in a transition between screen1 and screen2:

// screen1
...
Hero(
  tag: "someTag",
  child: Image.asset(
      "assets/large-image.jpg",
      width: 150.0
  ),
)

// screen2
...
child: PhotoView(
    imageProvider: AssetImage("assets/large-image.jpg"),
    heroTag: "someTag",
)

Result:
heroanim

This should be available in 0.0.6

from photo_view.

Related Issues (20)

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.