forked from firka/flutter
Update TabPageSelector Semantics Label Localization (#87430)
This commit is contained in:
@@ -1604,6 +1604,7 @@ class TabPageSelector extends StatelessWidget {
|
||||
final ColorTween selectedColorTween = ColorTween(begin: fixColor, end: fixSelectedColor);
|
||||
final ColorTween previousColorTween = ColorTween(begin: fixSelectedColor, end: fixColor);
|
||||
final TabController? tabController = controller ?? DefaultTabController.of(context);
|
||||
final MaterialLocalizations localizations = MaterialLocalizations.of(context);
|
||||
assert(() {
|
||||
if (tabController == null) {
|
||||
throw FlutterError(
|
||||
@@ -1624,7 +1625,7 @@ class TabPageSelector extends StatelessWidget {
|
||||
animation: animation,
|
||||
builder: (BuildContext context, Widget? child) {
|
||||
return Semantics(
|
||||
label: 'Page ${tabController.index + 1} of ${tabController.length}',
|
||||
label: localizations.tabLabel(tabIndex: tabController.index + 1, tabCount: tabController.length),
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: List<Widget>.generate(tabController.length, (int tabIndex) {
|
||||
|
||||
@@ -9,34 +9,41 @@ const Color kSelectedColor = Color(0xFF00FF00);
|
||||
const Color kUnselectedColor = Colors.transparent;
|
||||
|
||||
Widget buildFrame(TabController tabController, { Color? color, Color? selectedColor, double indicatorSize = 12.0 }) {
|
||||
return Directionality(
|
||||
textDirection: TextDirection.ltr,
|
||||
child: Theme(
|
||||
data: ThemeData(colorScheme: const ColorScheme.light().copyWith(secondary: kSelectedColor)),
|
||||
child: SizedBox.expand(
|
||||
child: Center(
|
||||
child: SizedBox(
|
||||
width: 400.0,
|
||||
height: 400.0,
|
||||
child: Column(
|
||||
children: <Widget>[
|
||||
TabPageSelector(
|
||||
controller: tabController,
|
||||
color: color,
|
||||
selectedColor: selectedColor,
|
||||
indicatorSize: indicatorSize,
|
||||
),
|
||||
Flexible(
|
||||
child: TabBarView(
|
||||
return Localizations(
|
||||
locale: const Locale('en', 'US'),
|
||||
delegates: const <LocalizationsDelegate<dynamic>>[
|
||||
DefaultMaterialLocalizations.delegate,
|
||||
DefaultWidgetsLocalizations.delegate,
|
||||
],
|
||||
child: Directionality(
|
||||
textDirection: TextDirection.ltr,
|
||||
child: Theme(
|
||||
data: ThemeData(colorScheme: const ColorScheme.light().copyWith(secondary: kSelectedColor)),
|
||||
child: SizedBox.expand(
|
||||
child: Center(
|
||||
child: SizedBox(
|
||||
width: 400.0,
|
||||
height: 400.0,
|
||||
child: Column(
|
||||
children: <Widget>[
|
||||
TabPageSelector(
|
||||
controller: tabController,
|
||||
children: const <Widget>[
|
||||
Center(child: Text('0')),
|
||||
Center(child: Text('1')),
|
||||
Center(child: Text('2')),
|
||||
],
|
||||
color: color,
|
||||
selectedColor: selectedColor,
|
||||
indicatorSize: indicatorSize,
|
||||
),
|
||||
),
|
||||
],
|
||||
Flexible(
|
||||
child: TabBarView(
|
||||
controller: tabController,
|
||||
children: const <Widget>[
|
||||
Center(child: Text('0')),
|
||||
Center(child: Text('1')),
|
||||
Center(child: Text('2')),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
@@ -3857,6 +3857,89 @@ void main() {
|
||||
final Tab firstTab = tester.widget(find.widgetWithIcon(Tab, Icons.check));
|
||||
expect(firstTab.height, 85);
|
||||
});
|
||||
|
||||
testWidgets('Test semantics of TabPageSelector', (WidgetTester tester) async {
|
||||
final SemanticsTester semantics = SemanticsTester(tester);
|
||||
|
||||
final TabController controller = TabController(
|
||||
vsync: const TestVSync(),
|
||||
length: 2,
|
||||
initialIndex: 0,
|
||||
);
|
||||
|
||||
await tester.pumpWidget(
|
||||
boilerplate(
|
||||
child: Column(
|
||||
children: <Widget>[
|
||||
TabBar(
|
||||
controller: controller,
|
||||
indicatorWeight: 30.0,
|
||||
tabs: const <Widget>[Tab(text: 'TAB1'), Tab(text: 'TAB2')],
|
||||
),
|
||||
Flexible(
|
||||
child: TabBarView(
|
||||
controller: controller,
|
||||
children: const <Widget>[Text('PAGE1'), Text('PAGE2')],
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
child: TabPageSelector(
|
||||
controller: controller
|
||||
)
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
final TestSemantics expectedSemantics = TestSemantics.root(
|
||||
children: <TestSemantics>[
|
||||
TestSemantics.rootChild(
|
||||
label: 'Tab 1 of 2',
|
||||
id: 1,
|
||||
rect: TestSemantics.fullScreen,
|
||||
children: <TestSemantics>[
|
||||
TestSemantics(
|
||||
label: 'TAB1\nTab 1 of 2',
|
||||
flags: <SemanticsFlag>[SemanticsFlag.isFocusable, SemanticsFlag.isSelected],
|
||||
id: 2,
|
||||
rect: TestSemantics.fullScreen,
|
||||
actions: 1,
|
||||
),
|
||||
TestSemantics(
|
||||
label: 'TAB2\nTab 2 of 2',
|
||||
flags: <SemanticsFlag>[SemanticsFlag.isFocusable],
|
||||
id: 3,
|
||||
rect: TestSemantics.fullScreen,
|
||||
actions: <SemanticsAction>[SemanticsAction.tap],
|
||||
),
|
||||
TestSemantics(
|
||||
id: 4,
|
||||
rect: TestSemantics.fullScreen,
|
||||
children: <TestSemantics>[
|
||||
TestSemantics(
|
||||
id: 6,
|
||||
rect: TestSemantics.fullScreen,
|
||||
actions: <SemanticsAction>[SemanticsAction.scrollLeft],
|
||||
children: <TestSemantics>[
|
||||
TestSemantics(
|
||||
id: 5,
|
||||
rect: TestSemantics.fullScreen,
|
||||
label: 'PAGE1'
|
||||
),
|
||||
]
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
);
|
||||
|
||||
expect(semantics, hasSemantics(expectedSemantics, ignoreRect: true, ignoreTransform: true));
|
||||
|
||||
semantics.dispose();
|
||||
});
|
||||
}
|
||||
|
||||
class KeepAliveInk extends StatefulWidget {
|
||||
|
||||
58
packages/flutter_localizations/test/material/tabs_test.dart
Normal file
58
packages/flutter_localizations/test/material/tabs_test.dart
Normal file
@@ -0,0 +1,58 @@
|
||||
// Copyright 2014 The Flutter Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
import 'dart:ui';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_localizations/flutter_localizations.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
void main() {
|
||||
testWidgets('Test semantics of TabPageSelector in pt-BR',
|
||||
(WidgetTester tester) async {
|
||||
final TabController controller = TabController(
|
||||
vsync: const TestVSync(),
|
||||
length: 2,
|
||||
initialIndex: 0,
|
||||
);
|
||||
|
||||
await tester.pumpWidget(
|
||||
Localizations(
|
||||
locale: const Locale('pt', 'BR'),
|
||||
delegates: const <LocalizationsDelegate<dynamic>>[
|
||||
GlobalMaterialLocalizations.delegate,
|
||||
GlobalWidgetsLocalizations.delegate,
|
||||
],
|
||||
child: Directionality(
|
||||
textDirection: TextDirection.ltr,
|
||||
child: Material(
|
||||
child: Column(
|
||||
children: <Widget>[
|
||||
TabBar(
|
||||
controller: controller,
|
||||
indicatorWeight: 30.0,
|
||||
tabs: const <Widget>[Tab(text: 'TAB1'), Tab(text: 'TAB2')],
|
||||
),
|
||||
Flexible(
|
||||
child: TabBarView(
|
||||
controller: controller,
|
||||
children: const <Widget>[Text('PAGE1'), Text('PAGE2')],
|
||||
),
|
||||
),
|
||||
Expanded(child: TabPageSelector(controller: controller)),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
final SemanticsHandle handle = tester.ensureSemantics();
|
||||
|
||||
expect(tester.getSemantics(find.byType(TabPageSelector)),
|
||||
matchesSemantics(label: 'Guia 1 de 2'));
|
||||
|
||||
handle.dispose();
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user