Home > Net >  Flutter styling unselected tab indicator
Flutter styling unselected tab indicator

Time:01-04

I am attempting to create a tab indicator in flutter with a topright and topleft border radius and manage to apply it to the active tab but cannot figure out how to apply it to the unselected tab indicator.

Below what i want to achieve

enter image description here

this is my exiting code

setColor(int tabIndex) {
    if (tabIndex == 0) {
      return const Color(0xFFFBD59E);
    } else if (tabIndex == 1) {
      return const Color(0xFFC8E0DA);
    } else if (tabIndex == 2) {
      return Colors.yellow;
    }
  }

    TabBar(
          labelStyle: const TextStyle(
             fontSize: 18.0, fontWeight: FontWeight.w600),
               onTap: (index) {
                 setState(() {
                          tabIndex = index;
                          setInactiveColor(index);
                        });
                      },
                      controller: _controller,
                      tabs: const [
                        Tab(
                          text: 'Tab 1',
                        ),
                        Tab(
                          text: 'Tab 2',
                        ),
                      ],
                      indicator: ShapeDecoration(
                        shape: const RoundedRectangleBorder(
                          borderRadius: BorderRadius.only(
                            topRight: Radius.circular(50),
                            topLeft: Radius.circular(50),
                          ),
                        ),
                        color: setColor(tabIndex),
                      ),
                    ),

And this what i get, is there anyway to style the unselected tab indicator?

enter image description here

CodePudding user response:

I don't think there is a way to style the default Tab widget the way you want just using properties of TabBar. Instead you can use another widget instead of Text for Tab's child.

TabBar(
      labelStyle: const TextStyle(fontSize: 18.0, fontWeight: FontWeight.w600),
      onTap: (index) {
        setState(() {
          tabIndex = index;
        });
      },
      controller: _controller,
      labelPadding: EdgeInsets.zero,
      tabs: [
        Tab(
          child: _buildTab(text: 'Tab 1', color: Colors.red),
        ),
        Tab(
          child: _buildTab(text: 'Tab 2', color: Colors.blue),
        ),
      ],
    ),

The _buidTab method is as follows:

_buildTab({required String text, required Color color}) {
    return Container(
      alignment: Alignment.center,
      width: double.infinity,
      decoration: ShapeDecoration(
        shape: const RoundedRectangleBorder(
          borderRadius: BorderRadius.only(
            topRight: Radius.circular(50),
            topLeft: Radius.circular(50),
          ),
        ),
        color: color,
      ),
      child: Text(text),
    );
  }

CodePudding user response:

You can use TabController to know the current selected tab That's how you can change the color of the tab's

 void initState() {
    super.initState();
    controller = TabController(
      length: 2,
      initialIndex: 1,
      vsync: this,
    );
    controller.addListener(() {
      setState(() {
        activeTabIndex = controller.index;
      });
    });
  }

See the full code:-

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

class StudentScreen extends StatefulWidget {
  @override
  _StudentScreenState createState() => _StudentScreenState();
}

class _StudentScreenState extends State<StudentScreen>
    with SingleTickerProviderStateMixin {
  late TabController controller;
  int activeTabIndex = 1;

  @override
  void initState() {
    super.initState();
    controller = TabController(
      length: 2,
      initialIndex: 1,
      vsync: this,
    );
    controller.addListener(() {
      setState(() {
        activeTabIndex = controller.index;
      });
    });
  }

  @override
  Widget build(BuildContext context) {
    return DefaultTabController(
        length: 2,
        child: Scaffold(
          appBar: AppBar(
            backgroundColor: Colors.white,
            elevation: 0,
            bottom: TabBar(
                controller: controller,
                padding: const EdgeInsets.all(0.0),
                isScrollable: false,
                unselectedLabelColor: Colors.black,
                // indicatorPadding: EdgeInsets.zero,
                // indicatorSize: TabBarIndicatorSize.label,
                indicator: const BoxDecoration(
                  borderRadius: BorderRadius.only(
                      topLeft: Radius.circular(30),
                      topRight: Radius.circular(30)),
                  // color: Color(0xFFFBD59E)
                ),
                tabs: [
                  Tab(
                    child: Container(
                      decoration: BoxDecoration(
                        color: activeTabIndex == 0
                            ? const Color(0xFFFBD59E)
                            : const Color(0xFFC8E0DA),
                        // color: Color(0xFFC8E0DA),
                        borderRadius: const BorderRadius.only(
                            topLeft: Radius.circular(30),
                            topRight: Radius.circular(30)),
                        // border:
                        //     Border.all(color: Colors.redAccent, width: 1)
                      ),
                      child: const Align(
                        alignment: Alignment.center,
                        child: Text("Tab one"),
                      ),
                    ),
                  ),
                  Tab(
                    child: Container(
                      decoration: BoxDecoration(
                        color: activeTabIndex == 1
                            ? const Color(0xFFFBD59E)
                            : const Color(0xFFC8E0DA),
                        borderRadius: const BorderRadius.only(
                            topLeft: Radius.circular(30),
                            topRight: Radius.circular(30)),
                        // border:
                        //     Border.all(color: Colors.redAccent, width: 1)
                      ),
                      child: const Align(
                        alignment: Alignment.center,
                        child: Text("Tab two"),
                      ),
                    ),
                  ),
                ]),
          ),
          body: const TabBarView(children: [
            Icon(Icons.apps),
            Icon(Icons.movie),
          ]),
        ));
  }
}

Output

First tab selected

Output

Second tab selected

Output

  • Related