How to use multiple tab for single page in Flutter

5.8k Views Asked by At

I create Tab Bar for my project. It includes two tabs and these each tabs are represent two pages.

Here is the code

import 'package:flutter/material.dart';

class TabView extends StatefulWidget {
  @override
  _TabViewState createState() => _TabViewState();
}

class _TabViewState extends State<TabView> with SingleTickerProviderStateMixin {
  TabController _tabController;

  @override
  void initState() {
    _tabController = TabController(length: 2, vsync: this);
    super.initState();
  }

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.grey.shade300,
      body: SafeArea(
        child: Padding(
          padding: const EdgeInsets.all(8.0),
          child: Column(
            children: [
              Container(
                height: 45,
                decoration: BoxDecoration(
                  color: Colors.grey.shade300,
                  borderRadius: BorderRadius.circular(
                    16.0,
                  ),
                ),
                child: TabBar(
                  controller: _tabController,
                  indicator: BoxDecoration(
                    borderRadius: BorderRadius.circular(
                      16.0,
                    ),
                    color: Colors.grey.shade900,
                  ),
                  labelColor: Colors.white,
                  unselectedLabelColor: Colors.grey.shade900,
                  tabs: [
                    Tab(
                      text: 'One',
                    ),
                    Tab(
                      text: 'Two',
                    ),
                  ],
                ),
              ),
              Expanded(
                child: TabBarView(
                  controller: _tabController,
                  children: [
                    Center(
                      child: Text(
                        'Page One',
                        style: TextStyle(
                          fontSize: 25,
                          fontWeight: FontWeight.w600,
                        ),
                      ),
                    ),
                    Center(
                      child: Text(
                        'Page Two',
                        style: TextStyle(
                          fontSize: 25,
                          fontWeight: FontWeight.w600,
                        ),
                      ),
                    ),
                  ],
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

Here is output

enter image description here

I want to use the tab bar for a single page to change a widget state.

Example

I want use the tab bar to change the color of the container in page one from red to blue and I don't want to switch to page two

enter image description here

How can I do it?

2

There are 2 best solutions below

0
Mol0ko On

TabBar is not quite suitable for this purpose, although it can be adapted. I suggest you to use CupertinoSegmentedControl from cupertino package. Here is docs, and here is code example:

enum _Tab { one, two }

class MyWidget extends StatefulWidget {
  @override
  State<StatefulWidget> createState() => _MyWidgetState();
}

class _MyWidgetState extends State<MyWidget> {
  _Tab _selectedTab = _Tab.one;

  @override
  Widget build(BuildContext context) {
    return Column(
      crossAxisAlignment: CrossAxisAlignment.stretch,
      children: [
        SizedBox(height: 16),
        CupertinoSegmentedControl<_Tab>(
          selectedColor: Colors.black,
          borderColor: Colors.black,
          pressedColor: Colors.grey,
          children: {
            _Tab.one: Text('One'),
            _Tab.two: Text('Two'),
          },
          onValueChanged: (value) {
            setState(() {
              _selectedTab = value;
            });
          },
          groupValue: _selectedTab,
        ),
        SizedBox(height: 64),
        Builder(
          builder: (context) {
            switch (_selectedTab) {
              case _Tab.one:
                return Center(
                  child: Container(
                    width: 100,
                    height: 100,
                    color: Colors.red,
                  ),
                );
              case _Tab.two:
                return Center(
                  child: Container(
                    width: 100,
                    height: 100,
                    color: Colors.blue,
                  ),
                );
            }
          },
        ),
      ],
    );
  }
}

Also take a look at CupertinoSlidingSegmentedControl.

1
kishan vekariya On
  • for your requirement don't use TabBarView at all, directly use container, change it's color value as per selectedtab index

    class Tabscreenstate extends State with TickerProviderStateMixin { int selectedTabIndex = 0; TabController tabController;

    @override
    void initState() {
      tabController = TabController(length: 2, vsync: this);
      tabController.addListener(() {
        setState(() {
          selectedTabIndex = tabController.index;
        });
      });
      super.initState();
    }
    
    
    @override
    Widget build(BuildContext context) {
      return Column(
          children: [
            tabbar(),
            Container(color:selectedTabIndex == 0 ? Colors.red : Colors.green),
          ],
        );
    }
    
    Widget tabbar() => TabBar(
          controller: tabController,
          onTap: (value) {
            setState(() {
              selectedTabIndex = value;
            });
          },
          tabs: [
            Text("tab one"),
            Text("tab two"),
          ],
        );
    }