infinite_cycle_carousel 1.0.0
infinite_cycle_carousel: ^1.0.0 copied to clipboard
Flutter package with configurable infinite, cylindrical, overlapping, stacked, and rotatory carousel widgets.
import 'package:flutter/material.dart';
import 'package:infinite_cycle_carousel/infinite_cycle_carousel.dart';
void main() => runApp(const CarouselExampleApp());
class CarouselExampleApp extends StatelessWidget {
const CarouselExampleApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.indigo),
useMaterial3: true,
),
home: const CarouselGallery(),
);
}
}
class CarouselGallery extends StatefulWidget {
const CarouselGallery({super.key});
@override
State<CarouselGallery> createState() => _CarouselGalleryState();
}
class _CarouselGalleryState extends State<CarouselGallery> {
static const colors = [
Color(0xff6750a4),
Color(0xff006a6a),
Color(0xffba1a1a),
Color(0xff825500),
Color(0xff3f51b5),
];
final _indicatorController = InfiniteCycleCarouselController();
final _controlledController = InfiniteCycleCarouselController();
int _controlledPage = 0;
@override
void dispose() {
_indicatorController.dispose();
_controlledController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Carousel Gallery')),
body: ListView(
padding: const EdgeInsets.only(bottom: 32),
children: [
_section('1. Basic autoplay carousel', _basicCarousel()),
_section('2. Indicator carousel', _indicatorCarousel()),
_section('3. Center-enlarged carousel', _enlargedCarousel()),
_section('4. Controlled carousel', _controlledCarousel()),
_section('5. Vertical carousel', _verticalCarousel()),
_section('6. Cylindrical 3D carousel', _cylindricalCarousel()),
_section('7. Overlapping ViewPager carousel', _overlappingCarousel()),
_section('8. Stacked carousel', _stackedCarousel()),
_section('9. Rotatory carousel', _rotatoryCarousel()),
],
),
);
}
Widget _section(String title, Widget carousel) {
return Padding(
padding: const EdgeInsets.fromLTRB(16, 20, 16, 4),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(title, style: Theme.of(context).textTheme.titleLarge),
const SizedBox(height: 12),
Align(
alignment: Alignment.center,
child: ConstrainedBox(
constraints: const BoxConstraints(maxWidth: 700),
child: carousel,
),
),
],
),
);
}
Widget _card(
int index, {
double? width,
double? height,
double colorOpacity = 1,
}) {
return Container(
width: width,
height: height,
margin: const EdgeInsets.symmetric(horizontal: 6, vertical: 8),
decoration: BoxDecoration(
color: colors[index % colors.length].withValues(alpha: colorOpacity),
borderRadius: BorderRadius.circular(20),
boxShadow: const [
BoxShadow(
color: Colors.black26,
blurRadius: 12,
offset: Offset(0, 6),
),
],
),
alignment: Alignment.center,
child: Text(
'Card ${index + 1}',
style: const TextStyle(
color: Colors.white,
fontSize: 24,
fontWeight: FontWeight.bold,
),
),
);
}
Widget _basicCarousel() {
return InfiniteCarousel(
items: List.generate(colors.length, _card),
options: const CarouselOptions(height: 190, autoPlay: true),
);
}
Widget _indicatorCarousel() {
return Column(
children: [
InfiniteCarousel(
controller: _indicatorController,
items: List.generate(colors.length, _card),
options: const CarouselOptions(
height: 190,
viewportFraction: 0.86,
autoPlay: true,
),
),
CarouselIndicator(
controller: _indicatorController,
itemCount: colors.length,
activeColor: Theme.of(context).colorScheme.primary,
inactiveColor: Theme.of(context).colorScheme.surfaceContainerHighest,
),
],
);
}
Widget _enlargedCarousel() {
return InfiniteCarousel(
items: List.generate(colors.length, _card),
options: const CarouselOptions(
height: 210,
viewportFraction: 0.82,
enlargeCenterPage: true,
enlargeFactor: 0.25,
),
);
}
Widget _controlledCarousel() {
return Column(
children: [
InfiniteCarousel(
controller: _controlledController,
items: List.generate(colors.length, _card),
options: CarouselOptions(
height: 190,
onPageChanged: (page) => setState(() => _controlledPage = page),
),
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
OutlinedButton(
onPressed: () => _controlledController.previousPage(),
child: const Text('Previous'),
),
const SizedBox(width: 12),
Text('${_controlledPage + 1} / ${colors.length}'),
const SizedBox(width: 12),
OutlinedButton(
onPressed: () => _controlledController.nextPage(),
child: const Text('Next'),
),
],
),
],
);
}
Widget _verticalCarousel() {
return InfiniteCarousel(
items: List.generate(colors.length, _card),
options: const CarouselOptions(
height: 230,
scrollDirection: Axis.vertical,
viewportFraction: 0.75,
autoPlay: true,
),
);
}
Widget _cylindricalCarousel() {
return CylindricalCarousel(
itemCount: colors.length,
height: 230,
itemWidth: 270,
radius: 320,
perspective: 0.0018,
enableGlassEffect: false,
itemBuilder: (context, index) => _card(index),
);
}
Widget _overlappingCarousel() {
return OverlappingCarousel(
itemCount: colors.length,
carouselHeight: 220,
config: const InfiniteCycleConfig(
viewportFraction: 0.82,
overlapFactor: -0.25,
autoScroll: true,
),
itemBuilder: (context, index) => _card(index),
);
}
Widget _stackedCarousel() {
return StackedCarousel(
itemCount: colors.length,
itemBuilder: (context, index) => _card(index),
);
}
Widget _rotatoryCarousel() {
return RotatoryInfiniteCarousel(
itemCount: colors.length,
height: 180,
itemBuilder: (context, index) => _card(index, colorOpacity: 0.82),
onItemTap: (index) {
ScaffoldMessenger.of(
context,
).showSnackBar(SnackBar(content: Text('Tapped card ${index + 1}')));
},
);
}
}