Search code examples
flutterdarttabcontainer

Scroll tabbar programmatically + Flutter


I want TabBar to scroll when user tap on previous/ next arrow. Not to change tab, just scroll. I check TabController properties, but didn't found anything for this. Is there any material widget available for same? Please share how can I achieve this feature?

UI ref


Solution

  • We can achieve this using scrollController. Use a ScrollController to control the horizontal scrolling of the TabBar. The scrollTabBar function is used to scroll the TabBar when the previous and next arrow buttons are pressed. This approach allows you to scroll the TabBar without changing the current tab index.

    import 'package:flutter/material.dart';
    
    void main() {
      runApp(MyApp());
    }
    
    class MyApp extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          home: TabBarDemo(),
        );
      }
    }
    
    class TabBarDemo extends StatefulWidget {
      @override
      _TabBarDemoState createState() => _TabBarDemoState();
    }
    
    class _TabBarDemoState extends State<TabBarDemo> with SingleTickerProviderStateMixin {
      late TabController _tabController;
      late ScrollController _scrollController;
    
      @override
      void initState() {
        super.initState();
        _tabController = TabController(length: 4, vsync: this);
        _scrollController = ScrollController();
      }
    
      @override
      void dispose() {
        _tabController.dispose();
        _scrollController.dispose();
        super.dispose();
      }
    
      void scrollTabBar(int scrollAmount) {
        if (_scrollController.hasClients) {
          final maxScrollExtent = _scrollController.position.maxScrollExtent;
          final newPosition = _scrollController.offset + scrollAmount;
          if (newPosition >= 0 && newPosition <= maxScrollExtent) {
            _scrollController.animateTo(
              newPosition,
              duration: Duration(milliseconds: 300),
              curve: Curves.ease,
            );
          }
        }
      }
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            title: Text('Scrollable TabBar Example'),
            actions: [
              IconButton(
                icon: Icon(Icons.arrow_back),
                onPressed: () {
                  scrollTabBar(-50); // Scroll to the left
                },
              ),
              IconButton(
                icon: Icon(Icons.arrow_forward),
                onPressed: () {
                  scrollTabBar(50); // Scroll to the right
                },
              ),
            ],
            bottom: TabBar(
              controller: _tabController,
              isScrollable: true,
              tabs: [
                Tab(text: 'Tab 1'),
                Tab(text: 'Tab 2'),
                Tab(text: 'Tab 3'),
                Tab(text: 'Tab 4'),
              ],
              controller: _tabController,
              labelColor: Colors.blue,
              unselectedLabelColor: Colors.black,
              indicatorSize: TabBarIndicatorSize.label,
            ),
          ),
          body: SingleChildScrollView(
            controller: _scrollController, // Control the scroll
            scrollDirection: Axis.horizontal,
            child: Row(
              children: [
                Container(
                  width: MediaQuery.of(context).size.width * 4, // Adjust width as needed
                  child: TabBarView(
                    controller: _tabController,
                    children: [
                      Center(child: Text('Tab 1 Content')),
                      Center(child: Text('Tab 2 Content')),
                      Center(child: Text('Tab 3 Content')),
                      Center(child: Text('Tab 4 Content')),
                    ],
                  ),
                ),
              ],
            ),
          ),
        );
      }
    }