proxibuy/lib/presentation/ui/widgets/carousel/carousel_slider_widget.dart

139 lines
4.8 KiB
Dart

import 'package:carousel_slider/carousel_slider.dart';
import 'package:flutter/material.dart';
import 'package:smooth_page_indicator/smooth_page_indicator.dart';
class CarouselSliderWidget<T> extends StatefulWidget {
final List<T> items;
final Widget Function(BuildContext context, T item, int index) onPageBuilder;
final bool withNavs;
final bool withInds;
final double? height;
final double viewportFraction;
final double aspectRatio;
final bool enlargeCenterPage;
final bool autoPlay;
final bool enableInfiniteScroll;
final Function()? onLastClick;
final Function(int index, CarouselPageChangedReason reason)? onPageChanged;
final CarouselSliderController? controller;
const CarouselSliderWidget({
super.key,
required this.items,
required this.onPageBuilder,
this.withNavs = false,
this.onLastClick,
this.autoPlay = true,
this.enableInfiniteScroll = true,
this.enlargeCenterPage = true,
this.height = 200,
this.viewportFraction = 0.9,
this.aspectRatio = 16 / 9,
this.withInds = true,
this.controller,
this.onPageChanged,
});
@override
State<CarouselSliderWidget<T>> createState() =>
_CarouselSliderWidgetState<T>();
}
class _CarouselSliderWidgetState<T> extends State<CarouselSliderWidget<T>> {
int activeIndex = 0;
late final CarouselSliderController _controller =
widget.controller ?? CarouselSliderController();
@override
Widget build(BuildContext context) {
return Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
CarouselSlider.builder(
carouselController: _controller,
itemCount: widget.items.length,
itemBuilder: (context, index, realIndex) {
return widget.onPageBuilder(context, widget.items[index], index);
},
options: CarouselOptions(
height: widget.height,
autoPlay: widget.autoPlay,
enableInfiniteScroll: widget.enableInfiniteScroll,
enlargeCenterPage: widget.enlargeCenterPage,
aspectRatio: widget.aspectRatio,
viewportFraction: widget.viewportFraction,
onPageChanged: (index, reason) {
widget.onPageChanged?.call(index, reason);
setState(() => activeIndex = index);
},
),
),
if (widget.withInds || widget.withNavs)
Padding(
padding: const EdgeInsets.all(16.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
if (widget.withInds)
Expanded(child: Center(child: buildIndicator())),
if (widget.withNavs)
Expanded(
child: Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
Opacity(
opacity: activeIndex != 0 ? 1 : 0,
child: IconButton(
icon: const Icon(Icons.arrow_back_ios_new_rounded),
onPressed: () => _controller.previousPage(),
),
),
Container(
padding: EdgeInsets.all(8),
decoration: BoxDecoration(
shape: BoxShape.circle,
color: Theme.of(context).primaryColor),
child: InkWell(
highlightColor: Theme.of(context).primaryColor,
onTap: () {
if (activeIndex == widget.items.length - 1) {
if (widget.onLastClick != null) {
widget.onLastClick!();
}
} else {
_controller.nextPage();
}
},
child: const Icon(Icons.arrow_forward_ios_rounded),
),
),
],
),
),
],
),
),
],
);
}
Widget buildImage(String urlImage, int index) => Container(
margin: const EdgeInsets.symmetric(horizontal: 12),
color: Colors.grey,
child: Image.network(
urlImage,
fit: BoxFit.cover,
),
);
Widget buildIndicator() => AnimatedSmoothIndicator(
activeIndex: activeIndex,
count: widget.items.length,
effect: ExpandingDotsEffect(
dotWidth: 10,
dotHeight: 10,
activeDotColor: Theme.of(context).primaryColor,
dotColor: Theme.of(context).colorScheme.onSurface,
),
);
}