observeTabController static method
- TabController controller, {
- List<
String> ? tabNames, - String? group,
- bool foldIntoScreenName = true,
Reports every selection change on controller as a ui.navigation
tab_switch span, and — unless foldIntoScreenName is false — folds the
selected tab into screen.name.
Listening to the controller — rather than intercepting onTap — is what
catches swipe-driven TabBarView changes as well as TabBar taps.
late final _tabs = TabController(length: 3, vsync: this);
TabObservation? _obs;
@override
void initState() {
super.initState();
_obs = VuTelemetry.observeTabController(
_tabs,
tabNames: const ['Taps', 'Values', 'Gestures'],
);
}
@override
void dispose() {
_obs?.dispose(); // the SDK owns the listener, you own the controller
_tabs.dispose();
super.dispose();
}
Prefer VuTabScope when you can wrap the widget instead — it handles the
lifetime for you. Pass group when a screen has more than one tab surface.
tabNames supplies the label per index; without it tabs report as tab_0,
tab_1, … A controller built with a non-zero initialIndex does not emit
a span merely by being observed.
Set foldIntoScreenName to false when the destinations are already
distinct routes (a shell over per-branch nested Navigators): the switch
still emits tab_switch with navigation.tab.*, but screen.name keeps
the branch's own name rather than gaining a redundant segment.
Implementation
static TabObservation observeTabController(
TabController controller, {
List<String>? tabNames,
String? group,
bool foldIntoScreenName = true,
}) {
return tab_tracking.observeTabController(
controller,
tabNames: tabNames,
group: group,
foldIntoScreenName: foldIntoScreenName,
);
}