-
Notifications
You must be signed in to change notification settings - Fork 29.7k
Closed
Labels
P0Critical issues such as a build break or regressionCritical issues such as a build break or regressiona: accessibilityAccessibility, e.g. VoiceOver or TalkBack. (aka a11y)Accessibility, e.g. VoiceOver or TalkBack. (aka a11y)customer: chalk (g3)engineflutter/engine related. See also e: labels.flutter/engine related. See also e: labels.f: material designflutter/packages/flutter/material repository.flutter/packages/flutter/material repository.frameworkflutter/packages/flutter repository. See also f: labels.flutter/packages/flutter repository. See also f: labels.platform-iosiOS applications specificallyiOS applications specificallywaiting for PR to land (fixed)A fix is in flightA fix is in flight
Description
Internal: b/275699766
While fixing #120650 and investigating #74963, I noticed that regular ListTile doesn't announce any action and other toggleable material widgets with voice-over doesn't sound right compared to Android.
Since these toggleable widgets are integrable parts of list tile-dependent widgets such as CheckboxListTile, SwitchListTile, RadioListTile, and ExpansionTile. I wanna make sure the hints are consistent on iOS for all these widgets.
Here I created an example that showcases toggleable Material widgets and their list tile variants.
code sample
import 'package:flutter/material.dart';
void main() => runApp(const MyApp());
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
theme: ThemeData(useMaterial3: true),
home: const Example(),
);
}
}
class Example extends StatefulWidget {
const Example({super.key});
@override
State<Example> createState() => _ExampleState();
}
class _ExampleState extends State<Example> {
bool toggle = false;
@override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: SingleChildScrollView(
child: Column(
children: <Widget>[
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
Column(
children: <Widget>[
const DescriptionText(text: 'Switch'),
Switch(
value: toggle,
onChanged: (bool value) {
setState(() {
toggle = !toggle;
});
},
),
],
),
Column(
children: <Widget>[
const DescriptionText(text: 'Checkbox'),
Checkbox(
value: toggle,
onChanged: (bool? value) {
setState(() {
toggle = !toggle;
});
},
),
],
),
Column(
children: <Widget>[
const DescriptionText(text: 'Radio'),
Radio<int>(
value: toggle ? 1 : 2,
groupValue: 1,
toggleable: true,
onChanged: (int? value) {
setState(() {
toggle = !toggle;
});
},
),
],
)
],
),
const Divider(),
const DescriptionText(text: 'ListTile'),
ListTile(
title: const Text('Headline'),
trailing: const Icon(Icons.favorite),
selected: toggle,
onTap: () {
setState(() {
toggle = !toggle;
});
},
),
const Divider(),
const DescriptionText(text: 'SwitchListTile'),
SwitchListTile(
title: const Text('Headline'),
value: toggle,
onChanged: (bool value) {
setState(() {
toggle = !toggle;
});
},
),
const Divider(),
const DescriptionText(text: 'CheckboxListTile'),
CheckboxListTile(
title: const Text('Headline'),
value: toggle,
onChanged: (bool? value) {
setState(() {
toggle = !toggle;
});
},
),
const Divider(),
const DescriptionText(text: 'RadioListTile'),
RadioListTile<int>(
title: const Text('Headline'),
value: toggle ? 1 : 2,
groupValue: 1,
toggleable: true,
onChanged: (int? value) {
setState(() {
toggle = !toggle;
});
},
),
const Divider(),
const DescriptionText(text: 'ExpansionTile'),
const ExpansionTile(
title: Text('Headline'),
children: <Widget>[FlutterLogo(size: 50)],
),
const Divider(),
],
),
),
),
);
}
}
class DescriptionText extends StatelessWidget {
const DescriptionText({super.key, required this.text});
final String text;
@override
Widget build(BuildContext context) {
return ExcludeSemantics(child: Text(text));
}
}
Preview
IMG_2211.MP4
IMG_2212.MP4
Observations
- All toggleable widgets are announced as 'switch button" on iOS.
- No double tap to expand announcement for expansion tile ExpansionTile accessibility information isn't read out in VoiceOver (iOS) #74963
- The radio button is never announced due to Flutter accessibility: there is no radioButton on Semantics #80182
Fix voiceover issues for the following widgets:
Metadata
Metadata
Assignees
Labels
P0Critical issues such as a build break or regressionCritical issues such as a build break or regressiona: accessibilityAccessibility, e.g. VoiceOver or TalkBack. (aka a11y)Accessibility, e.g. VoiceOver or TalkBack. (aka a11y)customer: chalk (g3)engineflutter/engine related. See also e: labels.flutter/engine related. See also e: labels.f: material designflutter/packages/flutter/material repository.flutter/packages/flutter/material repository.frameworkflutter/packages/flutter repository. See also f: labels.flutter/packages/flutter repository. See also f: labels.platform-iosiOS applications specificallyiOS applications specificallywaiting for PR to land (fixed)A fix is in flightA fix is in flight