infinite_scrollable_tabbar 0.0.1 copy "infinite_scrollable_tabbar: ^0.0.1" to clipboard
infinite_scrollable_tabbar: ^0.0.1 copied to clipboard

A fully customizable Flutter tab bar with infinite scrolling capability. Create horizontally scrollable tab bars where tabs repeat seamlessly in both directions.

Infinite Scrollable TabBar #

A Flutter package providing a fully customizable tab bar with infinite scrolling capability. Create horizontally scrollable tab bars where tabs repeat seamlessly in both directions, providing a fluid and engaging user experience.

Features #

  • ✨ Infinite Scrolling: Tabs repeat seamlessly in both directions for unlimited scrolling
  • 🎯 Smart Controller: Custom controller with intelligent index mapping for programmatic navigation
  • 🎨 Fully Customizable: Customize styles, indicators, tab builders, and more
  • 🎭 Smooth Animations: Built-in support for animated transitions between tabs
  • πŸ“± Responsive: Works seamlessly with dynamic tab lists
  • πŸš€ Easy Integration: Simple API with sensible defaults, works out of the box

Installation #

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

dependencies:
  infinite_scrollable_tabbar: ^0.0.1

Then run:

flutter pub get

Usage #

Basic Example #

import 'package:flutter/material.dart';
import 'package:infinite_scrollable_tabbar/infinite_scrollable_tabbar.dart';

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key});

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  late final InfiniteScrollableTabController _controller;
  late final List<TabItem> _tabs;

  @override
  void initState() {
    super.initState();

    _tabs = [
      const TabItem(label: 'Home'),
      const TabItem(label: 'Search'),
      const TabItem(label: 'Profile'),
      const TabItem(label: 'Settings'),
    ];

    _controller = InfiniteScrollableTabController(
      initialIndex: 0,
      tabCount: _tabs.length,
    );
  }

  @override
  void dispose() {
    _controller.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Column(
        children: [
          InfiniteScrollableTabBar(
            controller: _controller,
            tabs: _tabs,
            onTabTap: (index) {
              setState(() {});
              print('Tapped tab at index: $index');
            },
          ),
          Expanded(
            child: Center(
              child: Text('Selected: ${_tabs[_controller.currentIndex].label}'),
            ),
          ),
        ],
      ),
    );
  }
}

Customized Styling #

InfiniteScrollableTabBar(
  controller: _controller,
  tabs: _tabs,
  height: 70,
  tabWidth: 120,
  backgroundColor: Colors.deepPurple[50],
  selectedTabStyle: const TextStyle(
    fontSize: 18,
    fontWeight: FontWeight.bold,
    color: Colors.deepPurple,
  ),
  unselectedTabStyle: TextStyle(
    fontSize: 16,
    color: Colors.grey[600],
  ),
  indicatorBuilder: () => Container(
    width: 80,
    height: 4,
    decoration: BoxDecoration(
      gradient: const LinearGradient(
        colors: [Colors.deepPurple, Colors.purpleAccent],
      ),
      borderRadius: BorderRadius.circular(2),
    ),
  ),
  onTabTap: (index) {
    // Handle tab tap
  },
)

Tabs with Icons #

final tabs = [
  TabItem(
    label: 'Home',
    icon: const Icon(Icons.home),
  ),
  TabItem(
    label: 'Search',
    icon: const Icon(Icons.search),
  ),
  TabItem(
    label: 'Profile',
    icon: const Icon(Icons.person),
  ),
];

InfiniteScrollableTabBar(
  controller: _controller,
  tabs: tabs,
  height: 90,
  indicatorPosition: IndicatorPosition.top,
  onTabTap: (index) {
    // Handle tap
  },
)

Programmatic Scrolling #

The controller provides intelligent scrolling methods:

// Animate to a specific tab index using the shortest path
// Automatically determines whether to scroll forward or backward
_controller.animateToIndex(
  2,
  duration: const Duration(milliseconds: 500),
  curve: Curves.easeInOut,
);

// Jump to a tab instantly without animation
_controller.jumpToIndex(3);

// Get the current selected index
final currentIndex = _controller.currentIndex;

Tap vs Programmatic Scrolling:

  • Tap Behavior: When you tap a visible tab, it scrolls directly to that specific instance (natural feel)
  • Programmatic Behavior: animateToIndex() uses shortest-path logic, choosing the most efficient direction

This means tapping Tab 3 when you're at Tab 5 will scroll to the visible Tab 3 you tapped, while calling animateToIndex(2) programmatically will choose the shortest circular path.

Custom Tab Builder #

InfiniteScrollableTabBar(
  controller: _controller,
  tabs: _tabs,
  tabBuilder: (tab, isSelected) {
    return Container(
      padding: const EdgeInsets.all(12),
      decoration: BoxDecoration(
        color: isSelected ? Colors.blue : Colors.transparent,
        borderRadius: BorderRadius.circular(8),
      ),
      child: Text(
        tab.label,
        style: TextStyle(
          color: isSelected ? Colors.white : Colors.black,
          fontWeight: isSelected ? FontWeight.bold : FontWeight.normal,
        ),
      ),
    );
  },
)

API Reference #

InfiniteScrollableTabBar #

The main widget for displaying the infinite scrollable tab bar.

Properties

Property Type Default Description
controller InfiniteScrollableTabController required Controller for managing state and scrolling
tabs List<TabItem> required List of tab items to display
onTabTap ValueChanged<int>? null Callback when a tab is tapped
height double 56.0 Height of the tab bar
tabWidth double 100.0 Width of each tab
tabPadding EdgeInsets (16, 8) Padding for tab content
selectedTabStyle TextStyle? null Text style for selected tab
unselectedTabStyle TextStyle? null Text style for unselected tabs
tabBuilder Function? null Custom builder for tab content
indicatorBuilder Function? null Custom builder for indicator
indicatorPosition IndicatorPosition bottom Position of indicator (top/bottom)
backgroundColor Color? null Background color of tab bar
showIndicator bool true Whether to show the indicator
physics ScrollPhysics? null Physics for scroll behavior

InfiniteScrollableTabController #

Controller for managing the tab bar state and programmatic scrolling.

Constructor Parameters

Parameter Type Default Description
tabCount int required Total number of unique tabs
initialIndex int 0 Initial selected tab index
repetitions int 1000 Number of repetitions for infinite scrolling

Methods

  • animateToIndex(int index, {Duration?, Curve?, double?}): Smoothly animate to a tab using shortest path
  • animateToVirtualIndex(int virtualIndex, {Duration?, Curve?, double?}): Animate to a specific tab instance
  • jumpToIndex(int index, {double?}): Instantly jump to a tab using shortest path
  • dispose(): Clean up resources

Properties

  • currentIndex: Get the current selected tab index
  • scrollController: Access the underlying scroll controller

TabItem #

Data model representing a single tab.

Constructor Parameters

Parameter Type Required Description
label String yes Text label for the tab
icon Widget? no Optional icon widget
badge Widget? no Optional badge widget

Examples #

Check out the example directory for comprehensive demos including:

  • Basic usage with text tabs
  • Custom styled tabs
  • Tabs with icons
  • Programmatic scrolling
  • Dynamic tab management

To run the example:

cd example
flutter run

How It Works #

The infinite scrolling effect is achieved by:

  1. Virtual Repetition: The tabs are repeated multiple times (default: 1000) in the underlying scroll view
  2. Middle Positioning: The scroll view starts in the middle of the virtual list
  3. Smart Indexing: The controller maps real indices (0 to n-1) to virtual positions in the list
  4. Seamless Scrolling: Users can scroll in either direction indefinitely

This approach provides a true infinite scrolling experience while maintaining excellent performance.

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 #

  1. Fork the repository
  2. Create your feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add some amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

License #

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

Support #

If you find this package useful, please consider:

  • ⭐ Starring the repository
  • πŸ› Reporting bugs or requesting features via GitHub Issues
  • πŸ“– Contributing to the documentation

Acknowledgments #

Built with ❀️ using Flutter.

0
likes
150
points
--
downloads

Publisher

verified publisheraryak.dev

A fully customizable Flutter tab bar with infinite scrolling capability. Create horizontally scrollable tab bars where tabs repeat seamlessly in both directions.

Repository (GitHub)
View/report issues

Topics

#tabbar #tabs #infinite-scroll #scrollable #widget

Documentation

API reference

License

MIT (license)

Dependencies

flutter

More

Packages that depend on infinite_scrollable_tabbar