Skip to content

Each SwitchListTile receives TAB focus two times while only one is necessary  #77470

Closed

Description

@Leffe108

Steps to Reproduce

  1. Run flutter create tab.
  2. Update the files as follows:
lib/main.dart
import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  bool _state = true;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            SwitchListTile(
              title: Text('List Tile Caption'),
              value: _state,
              onChanged: (bool value) {
                setState(() {
                  _state = value;
                });
              },
            ),
            Container(height: 30),
            ElevatedButton(child: Text('Button'), onPressed: () {}),
          ],
        ),
      ),
    );
  }
}
  1. Start app in chrome
  2. Press Tab key several times and watch how tab focus is given first to the SwitchListTile row and then to the switch on the right and last to the button.

Expected results:
I expect that when I use TAB to navigate, I will not have to visit both the ListTileRow and the switch button. More precisely, I expect TAB to only visit the switch on the right.

Actual results:
Focus moves first to the SwitchListTile and then to the switch.

tab4.mp4

Discussion
If a UI contains multiple SwitchListTiles, I have to press TAB unnecessary many times to get past the switch list when navigating app using keyboard only (if app developer did not add and document shortcuts).

Since SwitchListTile onPressed callback do not get to know if user pressed on the list row or the switch handle, I don't see that it could break apps if this is changed so tab traversal only visit each SwitchListTile. Of course if the trailing or child has an element that can receive focus such as a button, then tab traversal would visit the ListTile more than once. But in this bug example the child is just a static Text().

Logs
Analyzing tab...
No issues found! (ran in 7.3s)
[✓] Flutter (Channel beta, 2.0.1, on Microsoft Windows [Version 10.0.19041.804], locale sv-SE)
    • Flutter version 2.0.1 at C:\Users\Leif\Programmering\Libraries\flutter
    • Framework revision c5a4b4029c (2 days ago), 2021-03-04 09:47:48 -0800
    • Engine revision 40441def69
    • Dart version 2.12.0

[✓] Android toolchain - develop for Android devices (Android SDK version 30.0.3)
    • Android SDK at C:\Users\Leif\Programmering\Android\android-sdks
    • Platform android-30, build-tools 30.0.3
    • Java binary at: C:\Program Files\Android\Android Studio\jre\bin\java
    • Java version OpenJDK Runtime Environment (build 1.8.0_242-release-1644-b01)
    • All Android licenses accepted.

[✓] Chrome - develop for the web
    • Chrome at C:\Program Files (x86)\Google\Chrome\Application\chrome.exe

[✓] Android Studio (version 4.1.0)
    • Android Studio at C:\Program Files\Android\Android Studio
    • Flutter plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/9212-flutter
    • Dart plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/6351-dart
    • Java version OpenJDK Runtime Environment (build 1.8.0_242-release-1644-b01)

[✓] VS Code, 32-bit edition (version 1.53.2)
    • VS Code at C:\Program Files (x86)\Microsoft VS Code
    • Flutter extension version 3.20.0

[✓] Connected device (2 available)
    • Chrome (web) • chrome • web-javascript • Google Chrome 88.0.4324.182
    • Edge (web)   • edge   • web-javascript • Microsoft Edge 88.0.705.81

• No issues found!

Activity

  1. TahaTesser commented on Mar 8, 2021

    @TahaTesser
    Contributor

    Hi @Leffe108
    Thanks for filing the issue, I can reproduce the issue on desktop and web, on mobile, it just focuses on SwitchListTile and you can switch without moving focus to the switch itself.

    Preview

    ezgif com-gif-maker

    code sample
    import 'package:flutter/material.dart';
    
    void main() {
      runApp(MyApp());
    }
    
    class MyApp extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          title: 'Flutter Demo',
          theme: ThemeData(
            primarySwatch: Colors.blue,
          ),
          home: MyHomePage(title: 'Flutter Demo Home Page'),
        );
      }
    }
    
    class MyHomePage extends StatefulWidget {
      MyHomePage({Key key, this.title}) : super(key: key);
    
      final String title;
    
      @override
      _MyHomePageState createState() => _MyHomePageState();
    }
    
    class _MyHomePageState extends State<MyHomePage> {
      bool _state = true;
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            title: Text(widget.title),
          ),
          body: Center(
            child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: <Widget>[
                SwitchListTile(
                  title: Text('List Tile Caption'),
                  value: _state,
                  onChanged: (bool value) {
                    setState(() {
                      _state = value;
                    });
                  },
                ),
                Container(height: 30),
                ElevatedButton(child: Text('Button'), onPressed: () {}),
              ],
            ),
          ),
        );
      }
    }
    
    flutter doctor -v
    [✓] Flutter (Channel stable, 2.0.1, on macOS 11.2.2 20D80 darwin-x64, locale
        en-GB)
        • Flutter version 2.0.1 at /Users/tahatesser/Code/flutter_stable
        • Framework revision c5a4b4029c (4 days ago), 2021-03-04 09:47:48 -0800
        • Engine revision 40441def69
        • Dart version 2.12.0
    
    [✓] Android toolchain - develop for Android devices (Android SDK version 30.0.3)
        • Android SDK at /Volumes/Extreme/SDK
        • Platform android-30, build-tools 30.0.3
        • ANDROID_HOME = /Volumes/Extreme/SDK
        • Java binary at: /Applications/Android
          Studio.app/Contents/jre/jdk/Contents/Home/bin/java
        • Java version OpenJDK Runtime Environment (build
          1.8.0_242-release-1644-b3-6915495)
        • All Android licenses accepted.
    
    [✓] Xcode - develop for iOS and macOS
        • Xcode at /Volumes/Extreme/Xcode.app/Contents/Developer
        • Xcode 12.4, Build version 12D4e
        • CocoaPods version 1.10.1
    
    [✓] Chrome - develop for the web
        • Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome
    
    [✓] Android Studio (version 4.1)
        • Android Studio at /Applications/Android Studio.app/Contents
        • Flutter plugin can be installed from:
          🔨 https://plugins.jetbrains.com/plugin/9212-flutter
        • Dart plugin can be installed from:
          🔨 https://plugins.jetbrains.com/plugin/6351-dart
        • Java version OpenJDK Runtime Environment (build
          1.8.0_242-release-1644-b3-6915495)
    
    [✓] VS Code (version 1.54.1)
        • VS Code at /Applications/Visual Studio Code.app/Contents
        • Flutter extension version 3.20.0
    
    [✓] Connected device (3 available)
        • Taha’s iPhone (mobile) • 00008020-001059882212002E • ios            • iOS
          14.4
        • macOS (desktop)        • macos                     • darwin-x64     •
          macOS 11.2.2 20D80 darwin-x64
        • Chrome (web)           • chrome                    • web-javascript •
          Google Chrome 88.0.4324.192
    
    • No issues found!
    [✓] Flutter (Channel master, 2.1.0-11.0.pre.145, on macOS 11.2.2 20D80
        darwin-x64, locale en-GB)
        • Flutter version 2.1.0-11.0.pre.145 at
          /Users/tahatesser/Code/flutter_master
        • Framework revision a0ba646408 (2 days ago), 2021-03-05 22:09:03 -0500
        • Engine revision f751d04fa0
        • Dart version 2.13.0 (build 2.13.0-107.0.dev)
    
    [✓] Android toolchain - develop for Android devices (Android SDK version 30.0.3)
        • Android SDK at /Volumes/Extreme/SDK
        • Platform android-30, build-tools 30.0.3
        • ANDROID_HOME = /Volumes/Extreme/SDK
        • Java binary at: /Applications/Android
          Studio.app/Contents/jre/jdk/Contents/Home/bin/java
        • Java version OpenJDK Runtime Environment (build
          1.8.0_242-release-1644-b3-6915495)
        • All Android licenses accepted.
    
    [✓] Xcode - develop for iOS and macOS
        • Xcode at /Volumes/Extreme/Xcode.app/Contents/Developer
        • Xcode 12.4, Build version 12D4e
        • CocoaPods version 1.10.1
    
    [✓] Chrome - develop for the web
        • Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome
    
    [✓] Android Studio (version 4.1)
        • Android Studio at /Applications/Android Studio.app/Contents
        • Flutter plugin can be installed from:
          🔨 https://plugins.jetbrains.com/plugin/9212-flutter
        • Dart plugin can be installed from:
          🔨 https://plugins.jetbrains.com/plugin/6351-dart
        • Java version OpenJDK Runtime Environment (build
          1.8.0_242-release-1644-b3-6915495)
    
    [✓] VS Code (version 1.54.1)
        • VS Code at /Applications/Visual Studio Code.app/Contents
        • Flutter extension version 3.20.0
    
    [✓] Connected device (3 available)
        • Taha’s iPhone (mobile) • 00008020-001059882212002E • ios            • iOS
          14.4
        • macOS (desktop)        • macos                     • darwin-x64     •
          macOS 11.2.2 20D80 darwin-x64
        • Chrome (web)           • chrome                    • web-javascript •
          Google Chrome 88.0.4324.192
    
    • No issues found!

    Thank you

  2. added
    a: accessibilityAccessibility, e.g. VoiceOver or TalkBack. (aka a11y)
    p: material_uimaterial_ui package in flutter/packages
    frameworkflutter/packages/flutter repository. See also f: labels.
    platform-webWeb applications specifically
    has reproducible stepsThe issue has been confirmed reproducible and is ready to work on
    and removed
    in triagePresently being triaged by the triage team
    on Mar 8, 2021
  3. added
    P2Important issues not at the top of the work list
    on Mar 11, 2021
  4. gspencergoog commented on Mar 11, 2021

    @gspencergoog
    Contributor
  5. Leffe108 commented on Mar 11, 2021

    @Leffe108
    Author

    I maybe should add that I have not checked if the same issue also applies to radio list tile and other similar widgets.

  6. gspencergoog commented on Mar 11, 2021

    @gspencergoog
    Contributor

    It probably does happen in ListTile, since SwitchListTile is just a thin wrapper around it.

    This is going to require some thought: since the title (or any of the slots) could be a focusable widget, we can't just make the ListTile unfocusable and the switch focusable. There might have to be some reworking of the ListTile to manage the focusability in a more fine-grained fashion.

  7. 3 remaining items

  8. dam-ease commented on May 9, 2023

    @dam-ease

    I am able to reproduce this issue on the latest master and stable channels. It's reproducible on Android, iOS, macOS and Web

    Test 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',
          theme: ThemeData(
            primarySwatch: Colors.blue,
          ),
          home: const MyHomePage(title: 'Flutter Demo Home Page'),
        );
      }
    }
    
    class MyHomePage extends StatefulWidget {
     const MyHomePage({super.key, required this.title});
    
      final String title;
    
      @override
      MyHomePageState createState() => MyHomePageState();
    }
    
    class MyHomePageState extends State<MyHomePage> {
      bool _state = true;
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            title: Text(widget.title),
          ),
          body: Center(
            child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: <Widget>[
                SwitchListTile(
                  title:  const Text('List Tile Caption'),
                  value: _state,
                  onChanged: (bool value) {
                    setState(() {
                      _state = value;
                    });
                  },
                ),
                Container(height: 30),
                ElevatedButton(child: const Text('Button'), onPressed: () {}),
              ],
            ),
          ),
        );
      }
    }
    flutter doctor -v
    [✓] Flutter (Channel master, 3.11.0-2.0.pre.55, on macOS 13.3 22E252 darwin-arm64, locale en-NG)
        • Flutter version 3.11.0-2.0.pre.55 on channel master at /Users/dammya/fvm/versions/master
        • Upstream repository https://github.com/flutter/flutter.git
        • Framework revision 835b892d7f (3 days ago), 2023-05-07 01:30:22 +0530
        • Engine revision 23f730efbf
        • Dart version 3.1.0 (build 3.1.0-83.0.dev)
        • DevTools version 2.23.1
    
    [✓] Android toolchain - develop for Android devices (Android SDK version 32.1.0-rc1)
        • Android SDK at /Users/dammya/Library/Android/sdk
        • Platform android-33, build-tools 32.1.0-rc1
        • ANDROID_HOME = /Users/dammya/Library/Android/sdk
        • Java binary at: /Applications/Android Studio.app/Contents/jre/Contents/Home/bin/java
        • Java version OpenJDK Runtime Environment (build 11.0.12+0-b1504.28-7817840)
        • All Android licenses accepted.
    
    [✓] Xcode - develop for iOS and macOS (Xcode 14.3)
        • Xcode at /Applications/Xcode.app/Contents/Developer
        • Build 14E222b
        • CocoaPods version 1.11.3
    
    [✓] Chrome - develop for the web
        • Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome
    
    [✓] Android Studio (version 2021.2)
        • Android Studio at /Applications/Android Studio.app/Contents
        • Flutter plugin can be installed from:
          🔨 https://plugins.jetbrains.com/plugin/9212-flutter
        • Dart plugin can be installed from:
          🔨 https://plugins.jetbrains.com/plugin/6351-dart
        • Java version OpenJDK Runtime Environment (build 11.0.12+0-b1504.28-7817840)
    
    [✓] IntelliJ IDEA Community Edition (version 2022.3.2)
        • IntelliJ at /Applications/IntelliJ IDEA CE.app
        • Flutter plugin can be installed from:
          🔨 https://plugins.jetbrains.com/plugin/9212-flutter
        • Dart plugin can be installed from:
          🔨 https://plugins.jetbrains.com/plugin/6351-dart
    
    [✓] VS Code (version 1.78.0)
        • VS Code at /Applications/Visual Studio Code.app/Contents
        • Flutter extension version 3.50.0
    
    [✓] VS Code (version 1.78.0)
        • VS Code at /Users/dammya/.Trash/Visual Studio Code 20.07.05.app/Contents
        • Flutter extension version 3.50.0
    
    [✓] Connected device (4 available)
        • sdk gphone arm64 (mobile)  • emulator-5554                        • android-arm64  • Android 11 (API 30) (emulator)
        • iPhone 14 Pro Max (mobile) • D7F3302D-D66F-4B89-B8CF-DBEE1CDB5449 • ios            • com.apple.CoreSimulator.SimRuntime.iOS-16-4 (simulator)
        • macOS (desktop)            • macos                                • darwin-arm64   • macOS 13.3 22E252 darwin-arm64
        • Chrome (web)               • chrome                               • web-javascript • Google Chrome 112.0.5615.137
    
    [✓] Network resources
        • All expected network resources are available.
    
    • No issues found!
    
    [✓] Flutter (Channel stable, 3.7.12, on macOS 13.3 22E252 darwin-arm64, locale
        en-NG)
        • Flutter version 3.7.12 on channel stable at /Users/dammya/sdks/flutter
        • Upstream repository https://github.com/flutter/flutter.git
        • Framework revision 4d9e56e694 (3 weeks ago), 2023-04-17 21:47:46 -0400
        • Engine revision 1a65d409c7
        • Dart version 2.19.6
        • DevTools version 2.20.1
    
    [✓] Android toolchain - develop for Android devices (Android SDK version
        32.1.0-rc1)
        • Android SDK at /Users/dammya/Library/Android/sdk
        • Platform android-33, build-tools 32.1.0-rc1
        • ANDROID_HOME = /Users/dammya/Library/Android/sdk
        • Java binary at: /Applications/Android
          Studio.app/Contents/jre/Contents/Home/bin/java
        • Java version OpenJDK Runtime Environment (build
          11.0.12+0-b1504.28-7817840)
        • All Android licenses accepted.
    
    [✓] Xcode - develop for iOS and macOS (Xcode 14.3)
        • Xcode at /Applications/Xcode.app/Contents/Developer
        • Build 14E222b
        • CocoaPods version 1.11.3
    
    [✓] Chrome - develop for the web
        • Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome
    
    [✓] Android Studio (version 2021.2)
        • Android Studio at /Applications/Android Studio.app/Contents
        • Flutter plugin can be installed from:
          🔨 https://plugins.jetbrains.com/plugin/9212-flutter
        • Dart plugin can be installed from:
          🔨 https://plugins.jetbrains.com/plugin/6351-dart
        • Java version OpenJDK Runtime Environment (build
          11.0.12+0-b1504.28-7817840)
    
    [✓] IntelliJ IDEA Community Edition (version 2022.3.2)
        • IntelliJ at /Applications/IntelliJ IDEA CE.app
        • Flutter plugin can be installed from:
          🔨 https://plugins.jetbrains.com/plugin/9212-flutter
        • Dart plugin can be installed from:
          🔨 https://plugins.jetbrains.com/plugin/6351-dart
    
    [✓] VS Code (version 1.78.0)
        • VS Code at /Applications/Visual Studio Code.app/Contents
        • Flutter extension version 3.50.0
    
    [✓] VS Code (version 1.78.0)
        • VS Code at /Users/dammya/.Trash/Visual Studio Code 20.07.05.app/Contents
        • Flutter extension version 3.50.0
    
    [✓] Connected device (4 available)
        • sdk gphone arm64 (mobile)  • emulator-5554                        •
          android-arm64  • Android 11 (API 30) (emulator)
        • iPhone 14 Pro Max (mobile) • D7F3302D-D66F-4B89-B8CF-DBEE1CDB5449 • ios
          • com.apple.CoreSimulator.SimRuntime.iOS-16-4 (simulator)
        • macOS (desktop)            • macos                                •
          darwin-arm64   • macOS 13.3 22E252 darwin-arm64
        • Chrome (web)               • chrome                               •
          web-javascript • Google Chrome 112.0.5615.137
    
    [✓] HTTP Host Availability
        • All required HTTP hosts are available
    
    • No issues found!
  9. galenwarren commented on May 18, 2023

    @galenwarren

    Is there any update on this issue or a workaround? Thanks!

  10. added
    r: fixedIssue is closed as already fixed in a newer version
    on Feb 13, 2024
  11. github-actions commented on Feb 27, 2024

    @github-actions

    This thread has been automatically locked since there has not been any recent activity after it was closed. If you are still experiencing a similar issue, please open a new bug, including the output of flutter doctor -v and a minimal reproduction of the issue.

  12. locked as resolved and limited conversation to collaborators on Feb 27, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    P2Important issues not at the top of the work lista: accessibilityAccessibility, e.g. VoiceOver or TalkBack. (aka a11y)a: desktopRunning on desktopf: focusFocus traversal, gaining or losing focusfound in release: 3.11Found to occur in 3.11found in release: 3.7Found to occur in 3.7frameworkflutter/packages/flutter repository. See also f: labels.has reproducible stepsThe issue has been confirmed reproducible and is ready to work onp: material_uimaterial_ui package in flutter/packagesr: fixedIssue is closed as already fixed in a newer versionteam-frameworkOwned by Framework team

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions