Home > Back-end >  Adding a custom widget to active tab of Flutter TabBar
Adding a custom widget to active tab of Flutter TabBar

Time:10-24

I need a TabBar and TabView as outlined in https://flutter.dev/docs/cookbook/design/tabs, but there is a twist: I need the ACTIVE tab to show an additional, custom widget.

If the user switches to a different tab, I need the custom widget to disappear from the previously active tab and a NEW custom widget to appear on the newly active tab.

Another way to explain this: all tabs need to host an instance of my custom widget, but the custom widgets should be hidden on all but the active tab.

How to achieve this please?

Many thanks

CodePudding user response:

Tab( ) widget can hold any widget, not just Text and icon

First, you need to identify which tab was selected.

Then, you need to perform an "if" (?) to decide which widget to display.

Use this code:

int selectedTab=1;
    TabBar(
        onTap: (index) {
          selectedTab = index;
        },

        tabs: [
          Tab(
              child: (selectedTab == 1) ? yourCustomWidget1 : yourWidget1
          ),
          Tab(
              child: (selectedTab == 2) ? yourCustomWidget2 : yourWidget2
          ),
        ]);

Let me know if this does not work

CodePudding user response:

It's all about state management. I did a sample using AnimatedBuilder with a TabController but you can customize to fill your needs.

Keep in mind: think declaratively this will help you to create any type of screen with any business logic.

Steps:

  • Get the current index
  • Listen when current index changes on all tabs
  • Verify if the tab index is the current index selected
    • If so, render the custom widget
    • Otherwise, just ignore, don't build anything

Dartpad Link

import 'package:flutter/material.dart';

void main() {
  runApp(const TabBarDemo());
}

class TabBarDemo extends StatefulWidget {
  const TabBarDemo({Key? key}) : super(key: key);

  @override
  _TabBarDemoState createState() => _TabBarDemoState();
}

class _TabBarDemoState extends State<TabBarDemo>
    with SingleTickerProviderStateMixin {
  late final TabController _controller;

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

    _controller = TabController(length: 3, vsync: this, initialIndex: 0);
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          bottom: TabBar(
            controller: _controller,
            tabs: [
              Tab(
                child: AnimatedBuilder(
                  animation: _controller,
                  builder: (context, chiild) {
                    return Row(
                      mainAxisAlignment: MainAxisAlignment.center,
                      children: [
                        const Icon(Icons.directions_car),
                        if (_controller.index == 0) const MyCustomWidget(),
                      ],
                    );
                  },
                ),
              ),
              Tab(
                child: AnimatedBuilder(
                  animation: _controller,
                  builder: (context, chiild) {
                    return Row(
                      mainAxisAlignment: MainAxisAlignment.center,
                      children: [
                        const Icon(Icons.directions_transit),
                        if (_controller.index == 1) const MyCustomWidget(),
                      ],
                    );
                  },
                ),
              ),
              Tab(
                child: AnimatedBuilder(
                  animation: _controller,
                  builder: (context, chiild) {
                    return Row(
                      mainAxisAlignment: MainAxisAlignment.center,
                      children: [
                        const Icon(Icons.directions_bike),
                        if (_controller.index == 2) const MyCustomWidget(),
                      ],
                    );
                  },
                ),
              ),
            ],
          ),
          title: const Text('Tabs Demo'),
        ),
        body: TabBarView(
          controller: _controller,
          children: const [
            Icon(Icons.directions_car),
            Icon(Icons.directions_transit),
            Icon(Icons.directions_bike),
          ],
        ),
      ),
    );
  }
}

class MyCustomWidget extends StatelessWidget {
  const MyCustomWidget({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Container(
      color: Colors.red,
      child: const Text('Your CustomWidget'),
    );
  }
}
  • Related