Last active
September 15, 2019 04:14
-
-
Save hnvn/1d06731129215709507011fd225dd5b9 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import 'dart:async'; | |
import 'package:flutter/cupertino.dart'; | |
import 'package:flutter/foundation.dart'; | |
import 'package:flutter/material.dart'; | |
import 'package:flutter/widgets.dart'; | |
import 'package:zoomable_image/zoomable_image.dart'; | |
import 'page_indicator.dart'; | |
class ImageCarousel extends StatefulWidget { | |
final List<ImageProvider> imageProviders; | |
final double height; | |
final TargetPlatform platform; | |
final Duration interval; | |
final bool allowZoom; | |
final PageController pageController; | |
final BoxFit fit; | |
// Images will shrink according to the value of [height] | |
// If you prefer to use the Material or Cupertino style activity indicator set the [platform] parameter | |
// Set [interval] to let the carousel loop through each photo automatically | |
// Pinch to zoom will be turned on by default | |
ImageCarousel(this.imageProviders, | |
{this.height = 250.0, | |
this.platform, | |
this.interval, | |
this.allowZoom = true, | |
this.pageController, | |
this.fit = BoxFit.cover}); | |
@override | |
State createState() => new _ImageCarouselState(); | |
} | |
class _ImageCarouselState extends State<ImageCarousel> { | |
PageController _pageController; | |
Timer _timer; | |
List<Widget> _widgets; | |
Duration _nextPageDuration = Duration(milliseconds: 300); | |
@override | |
void initState() { | |
super.initState(); | |
_widgets = widget.imageProviders | |
.map((ImageProvider provider) => new CarouselImageWidget( | |
widget, provider, widget.fit, widget.height)) | |
.toList(); | |
_pageController = widget.pageController ?? new PageController(); | |
if (widget.interval != null) { | |
_timer = new Timer.periodic(widget.interval, (_) { | |
_pageController.nextPage( | |
duration: _nextPageDuration, curve: Curves.fastOutSlowIn); | |
}); | |
} | |
} | |
@override | |
void dispose() { | |
_timer?.cancel(); | |
_pageController.dispose(); | |
super.dispose(); | |
} | |
@override | |
Widget build(BuildContext context) { | |
return new Stack( | |
children: [ | |
new SizedBox( | |
height: widget.height, | |
child: new PageView.builder( | |
controller: _pageController, | |
itemBuilder: (context, index) => _widgets[index % _widgets.length], | |
), | |
), | |
Positioned( | |
left: 0.0, | |
bottom: 0.0, | |
right: 0.0, | |
child: Padding( | |
padding: EdgeInsets.all(8.0), | |
child: DotsIndicator( | |
controller: _pageController, | |
itemCount: _widgets.length, | |
onPageSelected: (index) { | |
_pageController.animateToPage( | |
index, | |
duration: _nextPageDuration, | |
curve: Curves.fastOutSlowIn, | |
); | |
}, | |
), | |
), | |
) | |
], | |
); | |
} | |
} | |
class CarouselImageWidget extends StatefulWidget { | |
final ImageCarousel carousel; | |
final ImageProvider imageProvider; | |
final BoxFit fit; | |
final double height; | |
CarouselImageWidget(this.carousel, this.imageProvider, this.fit, this.height); | |
@override | |
State createState() => new _CarouselImageState(); | |
} | |
class _CarouselImageState extends State<CarouselImageWidget> { | |
bool _loading = true; | |
Widget _getIndicator(TargetPlatform platform) { | |
// if (platform == TargetPlatform.iOS) { | |
// return new CupertinoActivityIndicator(); | |
// } else { | |
return new Center( | |
child: new Container( | |
height: 24.0, | |
width: 24.0, | |
child: new CircularProgressIndicator(strokeWidth: 2.0,), | |
), | |
); | |
// } | |
} | |
void _toZoomRoute() { | |
Widget scaffold = new Scaffold( | |
appBar: new AppBar(), | |
body: new Center( | |
child: new ZoomableImage( | |
widget.imageProvider, | |
scale: 16.0, | |
), | |
), | |
); | |
Navigator.of(context).push( | |
defaultTargetPlatform == TargetPlatform.iOS | |
? new CupertinoPageRoute( | |
builder: (BuildContext context) => scaffold, | |
fullscreenDialog: true) | |
: new MaterialPageRoute( | |
builder: (BuildContext context) => scaffold, | |
fullscreenDialog: true), | |
); | |
} | |
@override | |
void initState() { | |
super.initState(); | |
widget.imageProvider.resolve(new ImageConfiguration()).addListener((i, b) { | |
if (mounted) { | |
setState(() { | |
_loading = false; | |
}); | |
} | |
}); | |
} | |
@override | |
Widget build(BuildContext context) { | |
return new Container( | |
height: widget.height, | |
child: _loading | |
? _getIndicator(widget.carousel.platform == null | |
? defaultTargetPlatform | |
: widget.carousel.platform) | |
: new GestureDetector( | |
child: new Image( | |
image: widget.imageProvider, | |
fit: widget.fit, | |
), | |
onTap: () { | |
if (widget.carousel.allowZoom) { | |
_toZoomRoute(); | |
} | |
}, | |
), | |
); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment