I want to click trough my ImageSlideshow in Flutter web. is this possible and how, now i only can swipe through it.
This is the Code
ImageSlideshow(
width: 400,
height: 800,
initialPage: 0,
indicatorColor: HexColor("#ff9900"),
indicatorBackgroundColor: Colors.grey,
children: [
Image.asset(
'third.png',
fit: BoxFit.cover,
),
Image.asset(
'second.png',
fit: BoxFit.cover,
),
Image.asset(
'first.png',
fit: BoxFit.cover,
),
],
onPageChanged: (value) {
print('Page changed: $value');
},
),
This is the Stateless part where the error was born.
class Information extends StatelessWidget {
PageController _pageController;
@override
void initState() {
_pageController = PageController(
initialPage: 0,
);
super.initState();
}
@override
void dispose() {
_pageController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return MaterialApp(
Thanks for any answer.
This feature isn't built into that package but when you run into that scenario you can copy the package code and modify it. The main difference is that you have to create your own PageController
and pass it into the ImageSlideShow
. Then wrap each of the children in a GestureDetector
and manually tell the _pageController
to animate to the next page in the onTap
.
Add this to your stateful widget where you have the ImageSlideShow
.
PageController _pageController;
@override
void initState() {
_pageController = PageController(
initialPage: 0,
);
super.initState();
}
@override
void dispose() {
_pageController.dispose();
super.dispose();
}
Create a new file and add this modified version of the package code. The only change is that it's using the PageController
that's passed in vs one created internally.
import 'dart:async';
import 'package:flutter/material.dart';
class MyImageSlideshow extends StatefulWidget {
MyImageSlideshow({
@required this.children,
@required this.pageController,
this.width = double.infinity,
this.height = 200,
this.initialPage = 0,
this.indicatorColor = Colors.blue,
this.indicatorBackgroundColor = Colors.grey,
this.onPageChanged,
});
final List<Widget> children;
final double width;
final double height;
final int initialPage;
final Color indicatorColor;
final Color indicatorBackgroundColor;
final ValueChanged<int> onPageChanged;
final PageController pageController;
@override
_MyImageSlideshowState createState() => _MyImageSlideshowState();
}
class _MyImageSlideshowState extends State<MyImageSlideshow> {
final StreamController<int> _pageStreamController =
StreamController<int>.broadcast();
void _onPageChanged(int value) {
_pageStreamController.sink.add(value);
if (widget.onPageChanged != null) {
widget.onPageChanged(value);
}
}
Widget _indicator(BuildContext context) {
return Wrap(
spacing: 4,
runSpacing: 4,
alignment: WrapAlignment.center,
children: List<Widget>.generate(
widget.children.length,
(index) {
return StreamBuilder<int>(
initialData: widget.pageController.initialPage,
stream: _pageStreamController.stream.where(
(pageIndex) {
return index >= pageIndex - 1 && index <= pageIndex + 1;
},
),
builder: (_, AsyncSnapshot<int> snapshot) {
return Container(
width: 6,
height: 6,
decoration: ShapeDecoration(
shape: CircleBorder(),
color: snapshot.data == index
? widget.indicatorColor
: widget.indicatorBackgroundColor,
),
);
},
);
},
),
);
}
@override
void initState() {
super.initState();
}
@override
void dispose() {
_pageStreamController.close();
super.dispose();
}
@override
Widget build(BuildContext context) {
return SizedBox(
width: widget.width,
height: widget.height,
child: Stack(
children: [
PageView.builder(
onPageChanged: _onPageChanged,
itemCount: widget.children.length,
controller: widget.pageController,
itemBuilder: (context, index) {
return widget.children[index];
},
),
Positioned(
left: 0.0,
right: 0.0,
bottom: 10.0,
child: _indicator(context),
),
],
),
);
}
}
Then on your page use the new custom MyImageSlideshow
instead with the added GestureDetectors
.
MyImageSlideshow(
pageController: _pageController,
width: 400,
height: 800,
initialPage: 0,
indicatorColor: HexColor("#ff9900"),
indicatorBackgroundColor: Colors.grey,
children: [
GestureDetector(
// this is where you're animating to the next picture
onTap: () {
if (_pageController.hasClients) {
_pageController.animateToPage(
1,
duration: const Duration(milliseconds: 400),
curve: Curves.easeInOut,
);
}
},
child: Image.asset(
'third.png',
fit: BoxFit.cover,
),
),
GestureDetector(
onTap: () {
if (_pageController.hasClients) {
_pageController.animateToPage(
2,
duration: const Duration(milliseconds: 400),
curve: Curves.easeInOut,
);
}
},
child: Image.asset(
'second.png',
fit: BoxFit.cover,
),
),
GestureDetector(
onTap: () {
if (_pageController.hasClients) {
_pageController.animateToPage(
0, // going back to first picture
duration: const Duration(milliseconds: 400),
curve: Curves.easeInOut,
);
}
},
child: Image.asset(
'first.png',
fit: BoxFit.cover,
),
),
],
onPageChanged: (value) {
print('Page changed: $value');
},
)
That should do it for 'ya.