Widget won't overlap other widget


Asked by Phil D on November 08, 2021 (source).

This is a TabBar which animates when the index is selected. Is there a way to make the long text LOOOOT that is animating not over-lapping the TabBar, or just animate behind the TabBar's layout?

enter image description here


class TabTest extends StatefulWidget {
  _TabTestState createState() => _TabTestState();

class _TabTestState extends State<TabTest> with TickerProviderStateMixin {
  late TabController _tabController;
  late List<AnimationController> _animationControllers;

  void initState() {
    _tabController = TabController(length: 4, vsync: this)
    _animationControllers = List.generate(
        (i) => AnimationController(
              vsync: this,
              duration: Duration(milliseconds: 750),
              reverseDuration: Duration(milliseconds: 350),

  Widget build(BuildContext context) {
    Widget _tab(IconData iconData, String text) {
      const _tabTextStyle = TextStyle(
          fontWeight: FontWeight.w300, fontSize: 12, color: Colors.black);
      return SizedBox(
        height: 50,
        child: Tab(
          icon: Icon(iconData, color: Colors.black),
          child: Text(text, style: _tabTextStyle),

    List<Widget> _tabs = [
      _tab(Icons.card_giftcard, 'LOOOOOOOTTTT'),
      _tab(Icons.confirmation_num_outlined, 'Voucher'),
      _tab(Icons.emoji_events_outlined, 'Testing'),
      _tab(Icons.wine_bar_outlined, 'Testing'),

    List<Widget> _animationGenerator() {
      return List.generate(
        (index) => AnimatedBuilder(
            animation: _animationControllers[index],
            builder: (ctx, child) {
              final child = _tabs[index];
              final value = _animationControllers[index].value;
              final angle = math.sin(value * math.pi * 2) * math.pi * 0.08;
              return Transform.rotate(angle: angle, child: child);

    return Scaffold(
      appBar: PreferredSize(
        preferredSize: Size.fromHeight(100),
        child: AppBar(
          iconTheme: Theme.of(context).iconTheme,
          title: Text(
            'Tab Bar',
            style: TextStyle(
              color: Colors.black,
              fontWeight: FontWeight.w400,
          centerTitle: true,
          bottom: PreferredSize(
            preferredSize: Size.fromHeight(20),
            child: Container(
              child: TabBar(
                controller: _tabController,
                labelPadding: EdgeInsets.only(top: 5.0, bottom: 2.0),
                indicatorColor: Colors.black,
                tabs: _animationGenerator(),
              decoration: BoxDecoration(
                color: Colors.white,
                boxShadow: [
                      color: Colors.white,
                      spreadRadius: 5.0,
                      offset: Offset(0, 3))
      body: TabBarView(
        controller: _tabController,
        children: List.generate(
            (index) => FittedBox(
                  child: Text('Tab $index'),

  void _listener() {
    if (_tabController.indexIsChanging) {
    } else {

  void dispose() {

This is what I have. No package used. Planning to animate the Container with bottom border of the selected Tab. (currently using SizedBox to wrap the Tab) and animate it behind the TabBar rather than over-lapping the TabBar.

EDIT: Include code


Question answered by Kaushik C (source).

Wrap the tab widget with a clipRect.