flutter / flutter

Flutter makes it easy and fast to build beautiful apps for mobile and beyond
https://flutter.dev
BSD 3-Clause "New" or "Revised" License
166.73k stars 27.62k forks source link

Figure out a way to inform developer about a11y string requires localizations #154537

Open gench23 opened 2 months ago

gench23 commented 2 months ago

Steps to reproduce

  1. Enable TalkBack/VoiceOver on your phone
  2. Set system language to italian (probably any other language different from english is ok)
  3. Run the sample code below and put the screen reader focus on an item of the bottom bar

Expected results

The screen reader should be reading the label and telling the user the number of the selected tab out of the total tabs present (i.e. "tab 1 of 3" in the sample code provided) in the correct language, italian in my case.

Actual results

The screen reader always reads "tab n of m" even though the locale is set to it-IT and the phone system language is italian.

Code sample

Code sample ```dart 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( title: 'Flutter Demo', locale: const Locale('it', 'IT'), theme: ThemeData( colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple), useMaterial3: true, ), home: const MyHomePage(title: 'Flutter Demo Home Page'), ); } } class MyHomePage extends StatefulWidget { const MyHomePage({super.key, required this.title}); final String title; @override State createState() => _MyHomePageState(); } class _MyHomePageState extends State { int _counter = 0; void _incrementCounter() { setState(() { _counter++; }); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( backgroundColor: Theme.of(context).colorScheme.inversePrimary, title: Text(widget.title), ), body: Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ const Text('You have pushed the button this many times:'), Text( '$_counter', style: Theme.of(context).textTheme.headlineMedium, ), ], ), ), floatingActionButton: FloatingActionButton( onPressed: _incrementCounter, tooltip: 'Increment', child: const Icon(Icons.add), ), bottomNavigationBar: BottomNavigationBar( items: const [ BottomNavigationBarItem(label: 'ciao', icon: Icon(Icons.abc)), BottomNavigationBarItem(label: 'ciao', icon: Icon(Icons.ac_unit)), BottomNavigationBarItem(label: 'ciao', icon: Icon(Icons.access_alarm)), ], ), ); } } ```

Screenshots or Video

Screenshots / Video demonstration [Upload media here]

Logs

Logs ```console [Paste your logs here] ```

Flutter Doctor output

Doctor output ```console Doctor summary (to see all details, run flutter doctor -v): [√] Flutter (Channel stable, 3.24.1, on Microsoft Windows [Version 10.0.26120.1542], locale it-IT) [√] Windows Version (Installed version of Windows is version 10 or higher) [!] Android toolchain - develop for Android devices (Android SDK version 34.0.0) X cmdline-tools component is missing Run `path/to/sdkmanager --install "cmdline-tools;latest"` See https://developer.android.com/studio/command-line for more details. X Android license status unknown. Run `flutter doctor --android-licenses` to accept the SDK licenses. See https://flutter.dev/to/windows-android-setup for more details. [√] Chrome - develop for the web [√] Visual Studio - develop Windows apps (Visual Studio Community 2022 17.8.1) [√] Android Studio (version 2024.1) [√] IntelliJ IDEA Community Edition (version 2024.2) [√] VS Code (version 1.92.2) [√] Connected device (3 available) [√] Network resources ! Doctor found issues in 1 category. ```
darshankawar commented 2 months ago

Thanks for the report @gench23 I verified this issue with voiceover running on iOS device on latest stable version. I selected Italian as device language and focused on BottomNavigationBar items, which properly read in Italian. I also verified with Spanish, and it read properly in Spanish.

Can you provide device details ? Did you test in Android or iOS ?

gench23 commented 2 months ago

Thank for the reply @darshankawar, I've tested it on a Pixel 6 running Android 14 and on an iPhone XR running 17.5.1. I'll try to rephrase the issue to make sure we're both on the same boat: what is happening is that the numbers are read in the correct language, but the line "tab n of m" is in english, while in italian it should be something like "tab n di m" or maybe "scheda 1 di 3".

darshankawar commented 2 months ago

while in italian it should be something like "tab n di m" or maybe "scheda 1 di 3".

I think that is what I observed while running on iOS. It reads the tab section in Italian properly, as shown below:

https://github.com/user-attachments/assets/bee84d3f-cfb9-4d54-aee8-ad895a62d878

If you are seeing different from above, please let us know.

gench23 commented 2 months ago

I'm seeing exactly what's shown in the video, but the part I highlighted in the screenshot from your video is not italian, as the VoiceOver is reading "tab 1 of 3", which is english. I know it's a bit subtle, but it's nonetheless incorrect.

image

Furthermore, I've noticed that this also happens with the default back button of the AppBar component, which reads "back" instead of its italian translation. You can verify it with the following code.

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(
      title: 'Flutter Demo',
      locale: const Locale('it', 'IT'),
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
        useMaterial3: true,
      ),
      home: const MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatelessWidget {
  const MyHomePage({super.key, required this.title});

  final String title;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Theme.of(context).colorScheme.inversePrimary,
        title: Text(title),
      ),
      body: Center(
        child: FilledButton(
          onPressed: () => Navigator.of(context).push(MaterialPageRoute(builder: (_) => const SecondPage())),
          child: const Text('Go to second page'),
        ),
      ),
      bottomNavigationBar: BottomNavigationBar(
        items: const [
          BottomNavigationBarItem(label: 'ciao', icon: Icon(Icons.abc)),
          BottomNavigationBarItem(label: 'ciao', icon: Icon(Icons.ac_unit)),
          BottomNavigationBarItem(label: 'ciao', icon: Icon(Icons.access_alarm)),
        ],
      ),
    );
  }
}

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Second Page'),
      ),
      body: const Center(
        child: Text('Go back!'),
      ),
    );
  }
}
darshankawar commented 2 months ago

I see now what you are saying. Yes, that's the current behavior observed as verified earlier.

Stable: 3.24.1
Master: 3.25.0-1.0.pre.219
chunhtai commented 2 months ago

Can you try adding the localization delegates?

return const MaterialApp(
  title: 'Localizations Sample App',
  localizationsDelegates: [ // Need to add these
    GlobalMaterialLocalizations.delegate,
    GlobalWidgetsLocalizations.delegate,
    GlobalCupertinoLocalizations.delegate,
  ],
  supportedLocales: [
    Locale('en'), // English
    Locale('es'), // Spanish
  ],
  home: MyHomePage(),
);
gench23 commented 2 months ago

Thanks for the reply @chunhtai, adding the localizations delegates with the correct supported locales worked. Maybe this could be specified in the accessibility page of the flutter documentation.

Anyway, thanks for the help 👍🏻

chunhtai commented 2 months ago

I agree this is not as straight forward as it is. We should have some way of inform developer about semantics label or hint that may require material localization.

Here are the widget I am aware:

Silvers - scroll actions ExpansionTile - semantics hint BottomNavigationBar - semantics labels

gench23 commented 2 months ago

There should be also the default BackButton of the AppBar