Repository: flutter
Issue: Scaffolds extendBody can disrupt focus traversal
Labels: platform-android,framework,f: material design,a: accessibility,has reproducible steps,P2,found in release: 2.2,found in release: 2.3,team-android,triaged-android

<!-- Thank you for using Flutter!

     If you are looking for support, please check out our documentation
     or consider asking a question on Stack Overflow:
      * https://flutter.dev/
      * https://api.flutter.dev/
      * https://stackoverflow.com/questions/tagged/flutter?sort=frequent

     If you have found a bug or if our documentation doesn't have an answer
     to what you're looking for, then fill out the template below. Please read
     our guide to filing a bug first: https://flutter.dev/docs/resources/bug-reports
-->

## Steps to Reproduce

<!-- You must include full steps to reproduce so that we can reproduce the problem. -->

Git: https://github.com/snaeji/flutter_accessibility_issues_demo

<details>
  <summary> Minimal code sample </summary>


```
import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter accessibility issues demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      home: MyHomePage(title: 'Flutter accessibility issues demo 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> {
  int _currentIndex = 0;
  bool _extendBody = false;
  List<Widget> bodyList = [SliderPage(), ListTilePage(), NestedListViewPage()];

  void onTap(int index) {
    setState(() {
      _currentIndex = index;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Container(
      child: Scaffold(
        appBar: AppBar(
          title: Text("Demo"),
          actions: [
            Tooltip(
              message: 'Til baka',
              child: FlatButton(
                child: Text(
                    _extendBody ? "Disable extend body" : "Enable extend body"),
                onPressed: () {
                  setState(() {
                    _extendBody = !_extendBody;
                  });
                },
              ),
            )
          ],
        ),
        body: bodyList[_currentIndex],
        extendBody: _extendBody,
        bottomNavigationBar: BottomNavigationBar(
          elevation: 0,
          type: BottomNavigationBarType.fixed,
          showUnselectedLabels: true,
          onTap: onTap,
          currentIndex: _currentIndex,
          items: [
            // Screen reader speaks the label text two times for each item
            // "Slider page example, Slider page example, tab 1 of 3, double tap to activate.
            BottomNavigationBarItem(
                label: 'Slider page example', icon: Icon(Icons.tv, size: 20.0)),
            BottomNavigationBarItem(
                label: 'Tiles in ListView',
                icon: Icon(Icons.radio, size: 20.0)),
            BottomNavigationBarItem(
                label: 'Nested ListView example',
                icon: Icon(Icons.live_tv, size: 20.0)),
          ],
        ),
      ),
    );
  }
}

class SliderPage extends StatefulWidget {
  const SliderPage({Key key}) : super(key: key);

  @override
  _SliderPageState createState() => _SliderPageState();
}

class _SliderPageState extends State<SliderPage> {
  double sliderValue = 0.0;
  double onChangeEndValue = 0.0;

  @override
  Widget build(BuildContext context) {
    return Column(
      mainAxisAlignment: MainAxisAlignment.center,
      children: [
        Text('sliderValue: $sliderValue'),
        Text('onChangeEnd: $onChangeEndValue'),
        Slider(
            value: sliderValue,
            min: 0.0,
            onChangeStart: (e) {
              print("onChangeStart: $e");
            },
            onChanged: (e) {
              print("onChanged: $e");
              setState(() {
                sliderValue = e;
              });
            },
            onChangeEnd: (e) {
              print("onChangeEnd: $e");
              setState(() {
                sliderValue = e;
                onChangeEndValue = e;
              });
            }),
      ],
    );
  }
}

class ListTilePage extends StatefulWidget {
  const ListTilePage({Key key}) : super(key: key);

  @override
  _ListTilePageState createState() => _ListTilePageState();
}

class _ListTilePageState extends State<ListTilePage> {
  double sliderValue = 0.0;
  double onChangeEndValue = 0.0;

  @override
  Widget build(BuildContext context) {
    return ListView(
        children: List<Widget>.generate(
            200, (index) => ListTile(title: Text('Item number $index'))));
  }
}

class NestedListViewPage extends StatefulWidget {
  @override
  _NestedListViewPageState createState() => _NestedListViewPageState();
}

class _NestedListViewPageState extends State<NestedListViewPage> {
  @override
  Widget build(BuildContext context) {
    return ListView(
      scrollDirection: Axis.vertical,
      children: List<Widget>.generate(
        50,
        (index1) => Container(
          height: 100,
          child: ListView(
            scrollDirection: Axis.horizontal,
            children: List<Widget>.generate(
                10,
                (index2) => GestureDetector(
                      onTap: () => null,
                      child: Center(child: Text('Row $index1, Line $index2')),
                    )),
          ),
        ),
      ),
    );
  }
}

```
</details>

1. Run minimal code sample or clone from git.
2. Move to Page 2 in the Bottom Tab Bar
3. Press the Enable extend body in the upper right corner
4. Enable talkback in System Settings > Accessibility > TalkBack  > Use Talkback 
5. Travel up and down the list 

**Expected results:** <!-- what did you want to see? -->

The focus should traverse up and down the list

**Actual results:** <!-- what did you see? -->

The focus moves to the BottomTabBar out of the list before reaching the end.

<details>
  <summary>Logs</summary>

<!--
      Run your application with `flutter run --verbose` and attach all the
      log output below between the lines with the backticks. If there is an
      exception, please see if the error message includes enough information
      to explain how to solve the issue.
-->

```
[ +690 ms] calculateSha: computing sha took 689us
[   +3 ms] ✓ Built build/app/outputs/flutter-apk/app-debug.apk.
[   +9 ms] executing: /Users/snaebjorn/Library/Android/sdk/build-tools/29.0.2/aapt dump xmltree /Users/snaebjorn/development/git/playground/flutter_accessibility_talkback/build/app/outputs/flutter-apk/app.apk AndroidManifest.xml
[  +24 ms] Exit code 0 from: /Users/snaebjorn/Library/Android/sdk/build-tools/29.0.2/aapt dump xmltree /Users/snaebjorn/development/git/playground/flutter_accessibility_talkback/build/app/outputs/flutter-apk/app.apk AndroidManifest.xml
[        ] N: android=http://schemas.android.com/apk/res/android
             E: manifest (line=2)
               A: android:versionCode(0x0101021b)=(type 0x10)0x1
               A: android:versionName(0x0101021c)="1.0.0" (Raw: "1.0.0")
               A: android:compileSdkVersion(0x01010572)=(type 0x10)0x1d
               A: android:compileSdkVersionCodename(0x01010573)="10" (Raw: "10")
               A: package="is.ruv.flutter_accessibility_talkback" (Raw: "is.ruv.flutter_accessibility_talkback")
               A: platformBuildVersionCode=(type 0x10)0x1d
               A: platformBuildVersionName=(type 0x10)0xa
               E: uses-sdk (line=7)
                 A: android:minSdkVersion(0x0101020c)=(type 0x10)0x10
                 A: android:targetSdkVersion(0x01010270)=(type 0x10)0x1d
               E: uses-permission (line=14)
                 A: android:name(0x01010003)="android.permission.INTERNET" (Raw: "android.permission.INTERNET")
               E: application (line=22)
                 A: android:label(0x01010001)="flutter_accessibility_talkback" (Raw: "flutter_accessibility_talkback")
                 A: android:icon(0x01010002)=@0x7f080000
                 A: android:name(0x01010003)="io.flutter.app.FlutterApplication" (Raw: "io.flutter.app.FlutterApplication")
                 A: android:debuggable(0x0101000f)=(type 0x12)0xffffffff
                 A: android:appComponentFactory(0x0101057a)="androidx.core.app.CoreComponentFactory" (Raw: "androidx.core.app.CoreComponentFactory")
                 E: activity (line=28)
                   A: android:theme(0x01010000)=@0x7f0a0000
                   A: android:name(0x01010003)="is.ruv.flutter_accessibility_talkback.MainActivity" (Raw: "is.ruv.flutter_accessibility_talkback.MainActivity")
                   A: android:launchMode(0x0101001d)=(type 0x10)0x1
                   A: android:configChanges(0x0101001f)=(type 0x11)0x40003fb4
                   A: android:windowSoftInputMode(0x0101022b)=(type 0x11)0x10
                   A: android:hardwareAccelerated(0x010102d3)=(type 0x12)0xffffffff
                   E: meta-data (line=42)
                     A: android:name(0x01010003)="io.flutter.embedding.android.NormalTheme" (Raw: "io.flutter.embedding.android.NormalTheme")
                     A: android:resource(0x01010025)=@0x7f0a0001
                   E: meta-data (line=52)
                     A: android:name(0x01010003)="io.flutter.embedding.android.SplashScreenDrawable" (Raw: "io.flutter.embedding.android.SplashScreenDrawable")
                     A: android:resource(0x01010025)=@0x7f040000
                   E: intent-filter (line=56)
                     E: action (line=57)
                       A: android:name(0x01010003)="android.intent.action.MAIN" (Raw: "android.intent.action.MAIN")
                     E: category (line=59)
                       A: android:name(0x01010003)="android.intent.category.LAUNCHER" (Raw: "android.intent.category.LAUNCHER")
                 E: meta-data (line=66)
                   A: android:name(0x01010003)="flutterEmbedding" (Raw: "flutterEmbedding")
                   A: android:value(0x01010024)=(type 0x10)0x2
[  +13 ms] Stopping app 'app.apk' on Pixel 4a.
[   +1 ms] executing: /Users/snaebjorn/Library/Android/sdk/platform-tools/adb -s 0B221JEC206250 shell am force-stop is.ruv.flutter_accessibility_talkback
[  +72 ms] executing: /Users/snaebjorn/Library/Android/sdk/platform-tools/adb -s 0B221JEC206250 shell pm list packages is.ruv.flutter_accessibility_talkback
[  +62 ms] package:is.ruv.flutter_accessibility_talkback
[   +7 ms] executing: /Users/snaebjorn/Library/Android/sdk/platform-tools/adb -s 0B221JEC206250 shell cat /data/local/tmp/sky.is.ruv.flutter_accessibility_talkback.sha1
[  +28 ms] 6a38a593543f9a53e4c866bcf35c56931082175f
[   +1 ms] Installing APK.
[   +1 ms] Installing build/app/outputs/flutter-apk/app.apk...
[        ] executing: /Users/snaebjorn/Library/Android/sdk/platform-tools/adb -s 0B221JEC206250 install -t -r /Users/snaebjorn/development/git/playground/flutter_accessibility_talkback/build/app/outputs/flutter-apk/app.apk
[+4184 ms] Performing Streamed Install
                    Success
[   +1 ms] Installing build/app/outputs/flutter-apk/app.apk... (completed in 4.2s)
[   +3 ms] executing: /Users/snaebjorn/Library/Android/sdk/platform-tools/adb -s 0B221JEC206250 shell echo -n 904f7cf3fca037367a2e80f07d3321a34b9f0c85 > /data/local/tmp/sky.is.ruv.flutter_accessibility_talkback.sha1
[  +23 ms] executing: /Users/snaebjorn/Library/Android/sdk/platform-tools/adb -s 0B221JEC206250 shell -x logcat -v time -t 1
[  +62 ms] --------- beginning of system
           05-18 15:17:53.344 W/BroadcastQueue( 1776): Background execution not allowed: receiving Intent { act=android.intent.action.PACKAGE_ADDED dat=package:is.ruv.flutter_accessibility_talkback flg=0x4000010 (has extras) } to com.google.android.ims/.receivers.RcsAutoStartReceiver
[  +14 ms] executing: /Users/snaebjorn/Library/Android/sdk/platform-tools/adb -s 0B221JEC206250 shell am start -a android.intent.action.RUN -f 0x20000000 --ez enable-background-compilation true --ez enable-dart-profiling true --ez enable-checked-mode true --ez verify-entry-points true
is.ruv.flutter_accessibility_talkback/is.ruv.flutter_accessibility_talkback.MainActivity
[ +105 ms] Starting: Intent { act=android.intent.action.RUN flg=0x20000000 cmp=is.ruv.flutter_accessibility_talkback/.MainActivity (has extras) }
[   +1 ms] Waiting for observatory port to be available...
[+1111 ms] Observatory URL on device: http://127.0.0.1:42093/2Yady1iOK9k=/
[   +1 ms] executing: /Users/snaebjorn/Library/Android/sdk/platform-tools/adb -s 0B221JEC206250 forward tcp:0 tcp:42093
[  +13 ms] 63732
[   +1 ms] Forwarded host port 63732 to device port 42093 for Observatory
[   +6 ms] Caching compiled dill
[  +75 ms] Connecting to service protocol: http://127.0.0.1:63732/2Yady1iOK9k=/
[ +349 ms] Launching a Dart Developer Service (DDS) instance at http://127.0.0.1:0, connecting to VM service at http://127.0.0.1:63732/2Yady1iOK9k=/.
[ +151 ms] DDS is listening at http://127.0.0.1:63737/ieTXLhLSBKE=/.
[  +69 ms] Successfully connected to service protocol: http://127.0.0.1:63732/2Yady1iOK9k=/
[+4040 ms] DevFS: Creating new filesystem on the device (null)
[  +53 ms] DevFS: Created new filesystem on the device (file:///data/user/0/is.ruv.flutter_accessibility_talkback/code_cache/flutter_accessibility_talkbackRCYOKO/flutter_accessibility_talkback/)
[   +8 ms] Updating assets
[  +99 ms] Syncing files to device Pixel 4a...
[   +1 ms] <- reset
[        ] Compiling dart to kernel with 0 updated files
[   +2 ms] <- recompile package:flutter_accessibility_talkback/main.dart 7c06aaed-fb3e-44c8-a6ef-19bfdb360f1e
[        ] <- 7c06aaed-fb3e-44c8-a6ef-19bfdb360f1e
[  +74 ms] Updating files.
[        ] DevFS: Sync finished
[        ] Syncing files to device Pixel 4a... (completed in 78ms)
[        ] Synced 0.0MB.
[   +1 ms] <- accept
[  +16 ms] Connected to _flutterView/0x6ff21a87b0.
[   +1 ms] Flutter run key commands.
[   +2 ms] r Hot reload. 🔥🔥🔥
[        ] R Hot restart.
[        ] h Repeat this help message.
[        ] d Detach (terminate "flutter run" but leave application running).
[        ] c Clear the screen
[        ] q Quit (terminate the application on the device).
[        ] An Observatory debugger and profiler on Pixel 4a is available at: http://127.0.0.1:63737/ieTXLhLSBKE=/
[        ] 
           Flutter DevTools, a Flutter debugger and profiler, on Pixel 4a is available at: http://127.0.0.1:9103?uri=http%3A%2F%2F127.0.0.1%3A63737%2FieTXLhLSBKE%3D%2F
[        ] Running with unsound null safety
[        ] For more information see https://dart.dev/null-safety/unsound-null-safety

```

<!--
     Run `flutter analyze` and attach any output of that command below.
     If there are any analysis errors, try resolving them before filing this issue.
-->

```
➜  flutter_accessibility_talkback git:(main) ✗ flutter analyze
Analyzing flutter_accessibility_talkback...                             

   info • 'FlatButton' is deprecated and shouldn't be used. Use TextButton instead. See the migration guide in flutter.dev/go/material-button-migration-guide). This feature was deprecated after v1.25.0-8.1.pre. • lib/main.dart:49:22 • deprecated_member_use

1 issue found. (ran in 6.0s)

```

<!-- Finally, paste the output of running `flutter doctor -v` here. -->

```
[✓] Flutter (Channel stable, 2.0.6, on macOS 11.3.1 20E241 darwin-x64, locale en-GB)
    • Flutter version 2.0.6 at /Users/snaebjorn/development/flutter
    • Framework revision 1d9032c7e1 (3 weeks ago), 2021-04-29 17:37:58 -0700
    • Engine revision 05e680e202
    • Dart version 2.12.3

[!] Android toolchain - develop for Android devices (Android SDK version 29.0.2)
    • Android SDK at /Users/snaebjorn/Library/Android/sdk
    • Platform android-S, build-tools 29.0.2
    • Java binary at: /Applications/Android Studio.app/Contents/jre/jdk/Contents/Home/bin/java
    • Java version OpenJDK Runtime Environment (build 11.0.8+10-b944.6916264)
    ✗ Android license status unknown.
      Run `flutter doctor --android-licenses` to accept the SDK licenses.
      See https://flutter.dev/docs/get-started/install/macos#android-setup for more details.

[✓] Xcode - develop for iOS and macOS
    • Xcode at /Applications/Xcode.app/Contents/Developer
    • Xcode 12.5, Build version 12E262
    • CocoaPods version 1.10.0

[✓] Chrome - develop for the web
    • Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome

[✓] Android Studio (version 4.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.8+10-b944.6916264)

[✓] IntelliJ IDEA Community Edition (version 2018.2.4)
    • IntelliJ at /Applications/IntelliJ IDEA CE.app
    • Flutter plugin version 29.0.4
    • Dart plugin version 182.4323.44

[✓] VS Code (version 1.54.3)
    • VS Code at /Applications/Visual Studio Code.app/Contents
    • Flutter extension version 3.20.0

[✓] Connected device (4 available)
    • Pixel 4a (mobile)   • 0B221JEC206250     • android-arm64  • Android 11 (API 30)
    • Chromecast (mobile) • 192.168.8.150:5555 • android-arm    • Android 10 (API 29)
    • macOS (desktop)     • macos              • darwin-x64     • macOS 11.3.1 20E241 darwin-x64
    • Chrome (web)        • chrome             • web-javascript • Google Chrome 90.0.4430.212
    ! Error: Living Room is not connected. Xcode will continue when Living Room is connected. (code -13)
    ! Error: Living Room is not connected. Xcode will continue when Living Room is connected. (code -13)
    ! Error: Auglysingadeild4thgen is not connected. Xcode will continue when Auglysingadeild4thgen is connected. (code -13)
    ! Error: Snaeji is not connected. Xcode will continue when Snaeji is connected. (code -13)

! Doctor found issues in 1 category.

```

</details>