onFocusChange property

TabValueChanged<bool>? onFocusChange
final

An optional callback that's called when a Tab's focus state in the TabBar changes.

Called when the node for the Tab at index gains or loses focus.

The value passed to the callback is true if the node has gained focus for the Tab at index and false if focus has been lost.

When focus is moved from one tab directly to another, this will be called twice. First to represent focus being lost by the initially focused tab, and then second for the next tab gaining focus.

This sample shows how to customize a Tab based on focus traversal in enclosing TabBar.

To see it in action, copy and run this code snippet on DartPad.

import 'package:material_ui/material_ui.dart';

/// Flutter code sample for [TabBar.onFocusChange].

void main() => runApp(const TabBarApp());

class TabBarApp extends StatelessWidget {
  const TabBarApp({super.key});

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(home: TabBarExample());
  }
}

class TabBarExample extends StatefulWidget {
  const TabBarExample({super.key});

  @override
  State<TabBarExample> createState() => _TabBarExampleState();
}

class _TabBarExampleState extends State<TabBarExample> {
  int? focusedIndex;

  @override
  Widget build(BuildContext context) {
    return DefaultTabController(
      initialIndex: 1,
      length: 3,
      child: Scaffold(
        appBar: AppBar(
          title: const Text('TabBar Sample'),
          bottom: TabBar(
            onFocusChange: (bool value, int index) {
              setState(() {
                focusedIndex = switch (value) {
                  true => index,
                  false => null,
                };
              });
            },
            tabs: <Widget>[
              Tab(
                icon: Icon(
                  Icons.cloud_outlined,
                  size: focusedIndex == 0 ? 35 : 25,
                ),
              ),
              Tab(
                icon: Icon(
                  Icons.beach_access_sharp,
                  size: focusedIndex == 1 ? 35 : 25,
                ),
              ),
              Tab(
                icon: Icon(
                  Icons.brightness_5_sharp,
                  size: focusedIndex == 2 ? 35 : 25,
                ),
              ),
            ],
          ),
        ),
        body: const TabBarView(
          children: <Widget>[
            Center(child: Text("It's cloudy here")),
            Center(child: Text("It's rainy here")),
            Center(child: Text("It's sunny here")),
          ],
        ),
      ),
    );
  }
}

Implementation

// TODO(framework): Replace the following block with a @dartpad directive
// when it's supported. https://github.com/dart-lang/dartdoc/issues/4123
/// {@macro material_ui.dartpad_guide}
///
/// {@example /example/lib/tabs/tab_bar.onFocusChange.dart#body}
///
/// </callout-box>
final TabValueChanged<bool>? onFocusChange;