📸 Easy to use yet very customizable zoomable image widget for Flutter, Photo View provides a gesture sensitive zoomable widget. Photo View is largely used to show interacive images and other stuff such as SVG.
MIT License
1.91k
stars
548
forks
source link
[BUG] Switching from portrait to landscape orientation in gallery mode skips ahead of selected image #313
Describe the bug
When in gallery mode and switching from portrait to landscape, the image displayed is not always the same and sometimes jumps 2 images ahead of the current one.
2. Select 3rd, 4th, or 5th picture (in portrait orientation)
3. Rotate the device
**What is the current behavior?**
Shown image is different from selected image after changing orientation
**Expected behavior**
Selected and shown image should be the same
**Screenshots**
![ezgif-6-da40573d94ce](https://user-images.githubusercontent.com/32480176/90272231-65d4ef80-de5d-11ea-801d-9b7ccf234cfc.gif)
**Is this a *feature* or report a *bug*?**
Bug
**Which versions of Flutter/Photo View, and which browser / OS are affected by this issue? Did this work in previous versions of Photo View?**
Flutter 1.20
photo_view: ^0.10.0
Describe the bug When in gallery mode and switching from portrait to landscape, the image displayed is not always the same and sometimes jumps 2 images ahead of the current one.
To Reproduce
void main() => runApp(MyApp());
class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( title: 'Welcome to Flutter', home: DemoPage(), ); } }
class DemoPage extends StatefulWidget { @override _DemoPageState createState() => _DemoPageState(); }
class _DemoPageState extends State {
List media = [
MediaItem(imgUrl: 'https://picsum.photos/seed/1/200/300'),
MediaItem(imgUrl: 'https://picsum.photos/seed/2/200/300'),
MediaItem(imgUrl: 'https://picsum.photos/seed/3/200/300'),
MediaItem(imgUrl: 'https://picsum.photos/seed/4/200/300'),
MediaItem(imgUrl: 'https://picsum.photos/seed/5/200/300'),
];
@override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: Text('Photo gallery')), body: GridView.builder( padding: const EdgeInsets.all(4.0), gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 3), itemCount: media?.length ?? 0, itemBuilder: (_, i) { return Container( margin: const EdgeInsets.all(4.0), child: GestureDetector( child: Image.network( media[i].imgUrl, fit: BoxFit.cover, ), onTap: () => Navigator.of(context).push( MaterialPageRoute( builder: (context) => PhotoView( options: Options( galleryItems: media, initialIndex: i, backgroundDecoration: const BoxDecoration( color: Colors.black, ), ), ), ), ), ), ); }, ), ); } }
class MediaItem { static int count = 0; final int id; final String imgUrl; final NetworkImage image;
MediaItem({this.imgUrl}) : id = count++, image = NetworkImage(imgUrl); }
class Options { final Decoration backgroundDecoration; final int initialIndex; final PageController pageController; final List galleryItems;
Options({ this.backgroundDecoration, this.initialIndex, @required this.galleryItems, }) : pageController = PageController(initialPage: initialIndex); }
class PhotoView extends StatefulWidget { final Options options;
PhotoView({this.options});
@override State createState() {
return _PhotoViewState();
}
}
class _PhotoViewState extends State {
int currentIndex;
@override void initState() { currentIndex = widget.options.initialIndex; super.initState(); }
void onPageChanged(int index) { setState(() { currentIndex = index; }); }
@override Widget build(BuildContext context) { return Scaffold( body: Container( decoration: widget.options.backgroundDecoration, constraints: BoxConstraints.expand( height: MediaQuery.of(context).size.height, ), child: Stack( alignment: Alignment.bottomRight, children:[
PhotoViewGallery.builder(
scrollPhysics: const BouncingScrollPhysics(),
builder: _buildItem,
itemCount: widget.options.galleryItems.length,
backgroundDecoration: widget.options.backgroundDecoration,
pageController: widget.options.pageController,
onPageChanged: onPageChanged,
),
Container(
padding: const EdgeInsets.all(20.0),
child: Text(
"Image ${currentIndex + 1}",
style: const TextStyle(
color: Colors.white,
fontSize: 17.0,
decoration: null,
),
),
)
],
),
),
);
}
PhotoViewGalleryPageOptions _buildItem(BuildContext context, int index) { final MediaItem item = widget.options.galleryItems[index]; return PhotoViewGalleryPageOptions( imageProvider: item.image, initialScale: PhotoViewComputedScale.contained, minScale: PhotoViewComputedScale.contained, maxScale: PhotoViewComputedScale.covered * 1.5, heroAttributes: PhotoViewHeroAttributes(tag: item.id), ); } }