Photo_view: [BUG] PhotoView when used with Hero(), loading widget is shown for cached image also, screen flashes with white overlay

Created on 14 Nov 2019  路  5Comments  路  Source: fireslime/photo_view

Describe the bug
A clear and concise description of what the bug is.

To Reproduce
Steps to reproduce the behavior.

I have used PhotoView within my Hero() class and whenever that class is getting called, the loader widget is getting shown for the cached image (_CachedImageNetworkProvider_) too also, the screen flashes with some kind of white color.

For example, a list of images is loaded in a listview, whenever a click is performed on the item, the item is loaded using Hero() function, if the image isn't loaded, the loading widget is shown which is good. Once the image is loaded, the image is shown. But when that same item is clicked again, the loader widget is shown for some seconds and then image loads and screen flashes.

My Widget class source:

import 'dart:async';
import 'dart:convert';

import 'package:cached_network_image/cached_network_image.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:dpbattle/helper/codecyan.dart' as CODECYAN;
import 'package:http/http.dart' as http;
import 'package:dpbattle/helper/photo_pojo.dart';
import 'package:flutter_cache_store/flutter_cache_store.dart';
import 'package:photo_view/photo_view.dart';

Future<List<PhotoPojo>> fetchPhotos(http.Client client) async {
  final response =
      await client.get('https://jsonplaceholder.typicode.com/photos');
  return compute(parsePhotos, response.body);
}

// A function that converts a response body into a List<Photo>.
List<PhotoPojo> parsePhotos(String responseBody) {
  final parsed = json.decode(responseBody).cast<Map<String, dynamic>>();
  return parsed.map<PhotoPojo>((json) => PhotoPojo.fromJson(json)).toList();
}

Widget homePhotosBody() {
  return FutureBuilder<List<PhotoPojo>>(
    future: fetchPhotos(http.Client()),
    builder: (context, snapshot) {
      if (snapshot.hasError) print(snapshot.error);

      return snapshot.hasData
          ? _photoBuild(photos: snapshot.data)
          : Center(child: CODECYAN.LOADER_WIDGET);
    },
  );
}

Widget _photoBuild({@required List<PhotoPojo> photos}) {
  return GridView.builder(
    gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
      crossAxisCount: 3,
    ),
    itemCount: photos.length,
    itemBuilder: (context, index) {
      return InkWell(
          onTap: () => Navigator.push(context, MaterialPageRoute(builder: (_) {
                return ShowFullScreen(index: index, image: photos[index].url);
              })),
          child: Hero(
              tag: 'photos_' + index.toString(),
              child: Padding(
                  padding: EdgeInsets.all(15),
                  child: CachedNetworkImage(
                      imageUrl: photos[index].thumbnailUrl))));
    },
  );
}

class ShowFullScreen extends StatelessWidget {
  final int index;
  final String image;

  ShowFullScreen({@required this.index, @required this.image});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.black,
      body: GestureDetector(
        child: Hero(
          tag: 'photos_' + index.toString(),
          child: PhotoView(
            loadingChild: CODECYAN.LOADER_WIDGET,
            imageProvider: CachedNetworkImageProvider(image),
            maxScale: 3.0,
            minScale: 0.6,
          ),
        ),
        onTap: () {
          Navigator.pop(context);
        },
      ),
    );
  }
}

Please check the video for a clear understanding.

Preview Video
View video

question

Most helpful comment

Have you tried to use PhotoViewHeroAttributes ?

When it is set, we do no even show the loading child.

All 5 comments

no update on this ? 馃憥

You should use PhotoViewHeroAttributes instead of wrapping the whole PhotoView widget with a hero.

Edit:

See how to use it here:
https://pub.dev/documentation/photo_view/latest/photo_view/PhotoView-class.html

Sorry to let you know, but this isn't working. Your suggestion suggests something else rather than fulfilling my expectations.

You suggested something else. This is a bug. Please check my issue again. Thanks.

Have you tried to use PhotoViewHeroAttributes ?

When it is set, we do no even show the loading child.

Have you tried to use PhotoViewHeroAttributes ?

When it is set, we do no even show the loading child.

perfect, working like a charm. I tried with PhotoViewHeroAttributes earlier but I think i missed something that time which caused the issue, but now it's perfect. Thanks a lot <3

Was this page helpful?
0 / 5 - 0 ratings