animated_cycler 1.0.4 copy "animated_cycler: ^1.0.4" to clipboard
animated_cycler: ^1.0.4 copied to clipboard

A versatile Flutter widget that automatically cycles through items with smooth bidirectional animations. Perfect for tickers, banners, news feeds, and rotating content.

AnimatedCycler #

pub package License: MIT Platform: Flutter

A versatile Flutter widget that automatically cycles through a list of items with smooth animations. Perfect for creating rolling tickers, rotating banners, news feeds, and any content that needs to be displayed in a cycling manner.

✨ Features #

  • Bidirectional Support: Both vertical and horizontal animation directions
  • Generic Type Safe: Works with any data type using Dart generics
  • Smooth Animations: Customizable animation curves and durations
  • Auto-play Control: Start, stop, pause, and resume functionality
  • Manual Navigation: Programmatically navigate to next, previous, or specific items
  • Flexible Styling: Complete control over item appearance through custom builders
  • Performance Optimized: Efficient rendering with minimal widget rebuilds
  • Easy Integration: Simple API with sensible defaults

πŸ“± Demo #

Vertical ranking ticker

Horizontal banner slider

Custom animations

πŸš€ Getting Started #

Installation #

Add this to your package's pubspec.yaml file:

dependencies:
  animated_cycler: ^1.0.0

Then run:

flutter pub get

Import #

import 'package:animated_cycler/animated_cycler.dart';

πŸ“± Usage Examples #

Basic Vertical Ticker #

Perfect for rankings, news headlines, or notifications:

AnimatedCycler<String>(
  direction: Axis.vertical,
  items: [
    'πŸ₯‡ John - 1,250 points',
    'πŸ₯ˆ Sarah - 1,180 points',
    'πŸ₯‰ Mike - 1,150 points',
    '4️⃣ Emma - 1,100 points',
  ],
  size: 60,
  itemBuilder: (context, item, index) {
    return Container(
      padding: EdgeInsets.symmetric(horizontal: 16),
      alignment: Alignment.centerLeft,
      decoration: BoxDecoration(
        color: Colors.blue.shade50,
        borderRadius: BorderRadius.circular(8),
      ),
      child: Text(
        item,
        style: TextStyle(
          fontSize: 16,
          fontWeight: FontWeight.w500,
          color: Colors.blue.shade700,
        ),
      ),
    );
  },
)

Horizontal Banner Slider #

Great for advertisements, promotions, or product showcases:

AnimatedCycler<Product>(
  direction: Axis.horizontal,
  items: productList,
  size: 300,
  displayDuration: Duration(seconds: 4),
  animationDuration: Duration(milliseconds: 600),
  itemBuilder: (context, product, index) {
    return Card(
      elevation: 4,
      child: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
          Image.network(product.imageUrl, height: 120),
          SizedBox(height: 8),
          Text(
            product.name,
            style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
          ),
          Text(
            '\$${product.price}',
            style: TextStyle(fontSize: 16, color: Colors.green),
          ),
        ],
      ),
    );
  },
  onItemTap: (product, index) {
    Navigator.push(
      context,
      MaterialPageRoute(
        builder: (context) => ProductDetailPage(product: product),
      ),
    );
  },
)

Using Named Constructors #

For cleaner code, use the direction-specific constructors:

// Vertical ticker
AnimatedCycler.vertical(
  items: notifications,
  height: 50,
  itemBuilder: (context, notification, index) {
    return NotificationTile(notification: notification);
  },
)

// Horizontal slider
AnimatedCycler.horizontal(
  items: banners,
  width: 350,
  itemBuilder: (context, banner, index) {
    return BannerCard(banner: banner);
  },
)

Advanced Usage with Manual Control #

class _MyPageState extends State<MyPage> {
  final GlobalKey<AnimatedCyclerState> _cyclerKey = GlobalKey();

  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        AnimatedCycler<String>(
          key: _cyclerKey,
          items: ['Item 1', 'Item 2', 'Item 3'],
          autoPlay: false, // Manual control
          itemBuilder: (context, item, index) {
            return Center(child: Text(item));
          },
        ),
        Row(
          mainAxisAlignment: MainAxisAlignment.spaceEvenly,
          children: [
            ElevatedButton(
              onPressed: () => _cyclerKey.currentState?.previousItem(),
              child: Icon(Icons.arrow_back),
            ),
            ElevatedButton(
              onPressed: () => _cyclerKey.currentState?.togglePlayPause(),
              child: Icon(Icons.play_pause),
            ),
            ElevatedButton(
              onPressed: () => _cyclerKey.currentState?.nextItem(),
              child: Icon(Icons.arrow_forward),
            ),
          ],
        ),
      ],
    );
  }
}

πŸŽ›οΈ API Reference #

Constructor Parameters #

Parameter Type Default Description
items List<T> required List of items to cycle through
itemBuilder Widget Function(BuildContext, T, int) required Builder function for rendering each item
direction Axis Axis.vertical Animation direction (vertical/horizontal)
displayDuration Duration 3 seconds How long each item is displayed
animationDuration Duration 800ms Duration of transition animation
size double 50.0 Widget size (height for vertical, width for horizontal)
autoPlay bool true Whether to automatically cycle through items
animationCurve Curve Curves.easeInOut Animation curve for transitions
loop bool true Whether to loop back to first item after last
onItemTap Function(T, int)? null Callback when an item is tapped
onAnimationComplete Function(T, int)? null Callback when animation completes

Named Constructors #

AnimatedCycler.vertical()

Optimized for vertical content like rankings, news feeds, notifications.

AnimatedCycler.horizontal()

Optimized for horizontal content like banners, product carousels, image sliders.

State Methods #

Access these methods through a GlobalKey<AnimatedCyclerState>:

Method Description
nextItem() Move to next item manually
previousItem() Move to previous item manually
goToIndex(int index) Jump to specific item by index
togglePlayPause() Toggle auto-play on/off
currentIndex Get current item index
currentItem Get current item data
isPlaying Check if auto-play is active

🎨 Customization Examples #

Custom Animation Curves #

AnimatedCycler<String>(
  items: ['Fast', 'Smooth', 'Bouncy'],
  animationCurve: Curves.bounceOut,
  animationDuration: Duration(milliseconds: 1200),
  itemBuilder: (context, item, index) {
    return Center(child: Text(item));
  },
)

Different Display Durations #

AnimatedCycler<String>(
  items: ['Quick', 'Normal', 'Slow'],
  displayDuration: Duration(seconds: 5), // Longer display time
  itemBuilder: (context, item, index) {
    return Center(child: Text(item));
  },
)

Responsive Sizing #

AnimatedCycler<String>(
  items: data,
  size: MediaQuery.of(context).size.width * 0.8, // 80% of screen width
  direction: Axis.horizontal,
  itemBuilder: (context, item, index) {
    return ResponsiveCard(data: item);
  },
)

πŸ§ͺ Testing #

To test widgets that use AnimatedCycler:

testWidgets('AnimatedCycler displays items correctly', (WidgetTester tester) async {
  final items = ['Test 1', 'Test 2', 'Test 3'];
  
  await tester.pumpWidget(
    MaterialApp(
      home: Scaffold(
        body: AnimatedCycler<String>(
          items: items,
          autoPlay: false, // Disable for testing
          itemBuilder: (context, item, index) {
            return Text(item, key: Key('item_$index'));
          },
        ),
      ),
    ),
  );

  // Verify first item is displayed
  expect(find.text('Test 1'), findsOneWidget);
  expect(find.text('Test 2'), findsNothing);
});

🀝 Contributing #

Contributions are welcome! Please feel free to submit a Pull Request. For major changes, please open an issue first to discuss what you would like to change.

Development Setup #

  1. Fork the repository
  2. Clone your fork: git clone https://github.com/BottlePumpkin/animated_cycler.git
  3. Create a feature branch: git checkout -b feature/amazing-feature
  4. Make your changes and add tests
  5. Run tests: flutter test
  6. Commit your changes: git commit -m 'Add amazing feature'
  7. Push to the branch: git push origin feature/amazing-feature
  8. Open a Pull Request

πŸ“„ License #

This project is licensed under the MIT License - see the LICENSE file for details.

πŸ™ Acknowledgments #

  • Inspired by ticker displays and carousel components
  • Built with ❀️ using Flutter
  • Thanks to the Flutter community for feedback and suggestions

πŸ“ž Support #

If you have any questions or issues, please:

  1. Check the example directory for usage examples
  2. Search existing issues
  3. Create a new issue if needed

⭐ If this package helped you, please give it a star on GitHub and a like on pub.flutter-io.cn!

10
likes
150
points
72
downloads
screenshot

Publisher

unverified uploader

Weekly Downloads

A versatile Flutter widget that automatically cycles through items with smooth bidirectional animations. Perfect for tickers, banners, news feeds, and rotating content.

Repository (GitHub)
View/report issues

Topics

#widget #animation #carousel #ticker #banner

Documentation

API reference

License

MIT (license)

Dependencies

flutter

More

Packages that depend on animated_cycler