CupertinoTabBar requires Localizations parent
Summary
#Instances of CupertinoTabBar
must have a Localizations
parent in order to provide a localized Semantics
hint. Trying to instantiate a CupertinoTabBar
without localizations results in an assertion such as the following:
CupertinoTabBar requires a Localizations parent in order to provide an appropriate Semantics hint
for tab indexing. A CupertinoApp provides the DefaultCupertinoLocalizations, or you can
instantiate your own Localizations.
'package:flutter/src/cupertino/bottom_tab_bar.dart':
Failed assertion: line 213 pos 7: 'localizations != null'
Context
#To support localized semantics information, the CupertinoTabBar
requires localizations.
Before this change, the Semantics
hint provided to the CupertinoTabBar
was a hard-coded String, 'tab, $index of $total'. The content of the semantics hint was also updated from this original String to 'Tab $index of $total' in English.
If your CupertinoTabBar
is within the scope of a CupertinoApp
, the DefaultCupertinoLocalizations
is already instantiated and may suit your needs without having to make a change to your existing code.
If your CupertinoTabBar
is not within a CupertinoApp
, you may provide the localizations of your choosing using the Localizations
widget.
Migration guide
#If you are seeing a 'localizations != null'
assertion error, make sure locale information is being provided to your CupertinoTabBar
.
Code before migration:
import 'package:flutter/cupertino.dart';
void main() => runApp(Foo());
class Foo extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MediaQuery(
data: const MediaQueryData(),
child: CupertinoTabBar(
items: const <BottomNavigationBarItem>[
BottomNavigationBarItem(
icon: Icon(CupertinoIcons.add_circled),
label: 'Tab 1',
),
BottomNavigationBarItem(
icon: Icon(CupertinoIcons.add_circled_solid),
label: 'Tab 2',
),
],
currentIndex: 1,
),
);
}
}
Code after migration (Providing localizations via the CupertinoApp
):
import 'package:flutter/cupertino.dart';
void main() => runApp(Foo());
class Foo extends StatelessWidget {
@override
Widget build(BuildContext context) {
return CupertinoApp(
home: CupertinoTabBar(
items: const <BottomNavigationBarItem>[
BottomNavigationBarItem(
icon: Icon(CupertinoIcons.add_circled),
label: 'Tab 1',
),
BottomNavigationBarItem(
icon: Icon(CupertinoIcons.add_circled_solid),
label: 'Tab 2',
),
],
currentIndex: 1,
),
);
}
}
Code after migration (Providing localizations by using the Localizations
widget):
import 'package:flutter/cupertino.dart';
void main() => runApp(Foo());
class Foo extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Localizations(
locale: const Locale('en', 'US'),
delegates: <LocalizationsDelegate<dynamic>>[
DefaultWidgetsLocalizations.delegate,
DefaultCupertinoLocalizations.delegate,
],
child: MediaQuery(
data: const MediaQueryData(),
child: CupertinoTabBar(
items: const <BottomNavigationBarItem>[
BottomNavigationBarItem(
icon: Icon(CupertinoIcons.add_circled),
label: 'Tab 1',
),
BottomNavigationBarItem(
icon: Icon(CupertinoIcons.add_circled_solid),
label: 'Tab 2',
),
],
currentIndex: 1,
),
),
);
}
}
Timeline
#Landed in version: 1.18.0-9.0.pre
In stable release: 1.20.0
References
#API documentation:
CupertinoTabBar
Localizations
DefaultCupertinoLocalizations
Semantics
CupertinoApp
- Internationalizing Flutter Apps
Relevant PR:
- PR 55336: Adding tabSemanticsLabel to CupertinoLocalizations
- PR 56582: Update Tab semantics in Cupertino to be the same as Material
Unless stated otherwise, the documentation on this site reflects the latest stable version of Flutter. Page last updated on 2024-04-04. View source or report an issue.