infinite_cycle_carousel 1.0.0 copy "infinite_cycle_carousel: ^1.0.0" to clipboard
infinite_cycle_carousel: ^1.0.0 copied to clipboard

Flutter package with configurable infinite, cylindrical, overlapping, stacked, and rotatory carousel widgets.

example/lib/main.dart

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}')));
      },
    );
  }
}
2
likes
160
points
91
downloads

Documentation

API reference

Publisher

unverified uploader

Weekly Downloads

Flutter package with configurable infinite, cylindrical, overlapping, stacked, and rotatory carousel widgets.

Repository (GitHub)
View/report issues

License

MIT (license)

Dependencies

flutter

More

Packages that depend on infinite_cycle_carousel