Repository: flutter
Issue: [Android][a11y] Invisible items in list are not read
Labels: platform-android,framework,engine,a: accessibility,f: scrolling,has reproducible steps,P2,team-android,triaged-android,found in release: 3.16,found in release: 3.20

### Steps to reproduce

1. Run the sample code below
2. in Android, turn on Talkback
3. swipe from left to right to visit all items in List 1 and List 2

Note: Issue only happens on Android, it works as expected on iOS

### Expected results

A11y Focus will move through all items in List 1 (from `1 - item 0` to `1 - item 19`), then continue with first item in List 2, and go through all items in List 2

### Actual results

When a11y focus reaches the last visible item in List 1, it continues with first visible item in List 2, ignore the rest of items in List 1

### Code sample

<details open><summary>Code sample</summary>

```dart
import 'package:flutter/material.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      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<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Theme.of(context).colorScheme.inversePrimary,
        title: Text(widget.title),
      ),
      body: Center(
        child: SizedBox(
          height: 400,
          child: SingleChildScrollView(
            physics: const BouncingScrollPhysics(),
              child: Row(
            children: [
              Expanded(
                  child: ListView.separated(
                      shrinkWrap: true,
                  physics: const NeverScrollableScrollPhysics(),
                      itemBuilder: (context, index) => Padding(
                            padding: const EdgeInsets.all(8.0),
                            child: Text('1 - item $index'),
                          ),
                      separatorBuilder: (context, index) => const Divider(),
                      itemCount: 20)),
              const SizedBox(
                width: 30,
              ),
              Expanded(
                  child: ListView.separated(
                      shrinkWrap: true,
                      physics: const NeverScrollableScrollPhysics(),
                      itemBuilder: (context, index) => Padding(
                            padding: const EdgeInsets.all(8.0),
                            child: Text('2 - item $index'),
                          ),
                      separatorBuilder: (context, index) => const Divider(),
                      itemCount: 20)),
            ],
          )),
        ),
      ),
    );
  }
}
```

</details>


### Screenshots or Video

<details open>
<summary>Screenshots / Video demonstration</summary>

https://github.com/flutter/flutter/assets/117876531/1a084316-6b14-44d7-892c-82c0ca3344b6



</details>


### Logs

<details open><summary>Logs</summary>

```console
Launching lib/main.dart on SM G990E in debug mode...
Running Gradle task 'assembleDebug'...
✓  Built build/app/outputs/flutter-apk/app-debug.apk.
Installing build/app/outputs/flutter-apk/app-debug.apk...
Debug service listening on ws://127.0.0.1:63221/G7jww04KUFk=/ws
Syncing files to device SM G990E...
I/ViewRootImpl@3d3bb82[MainActivity](24178): performTraversals params={(0,0)(fillxfill) sim={adjust=resize forwardNavigation} ty=BASE_APPLICATION fmt=TRANSLUCENT wanim=0x1030001
I/ViewRootImpl@3d3bb82[MainActivity](24178):   fl=81810100
I/ViewRootImpl@3d3bb82[MainActivity](24178):   pfl=16020040
I/ViewRootImpl@3d3bb82[MainActivity](24178):   vsysui=500
I/ViewRootImpl@3d3bb82[MainActivity](24178):   apr=LIGHT_STATUS_BARS
I/ViewRootImpl@3d3bb82[MainActivity](24178):   bhv=DEFAULT
I/ViewRootImpl@3d3bb82[MainActivity](24178):   fitSides= naviIconColor=0}
I/ViewRootImpl@3d3bb82[MainActivity](24178): performTraversals mFirst=false windowShouldResize=false viewVisibilityChanged=false mForceNextWindowRelayout=false params={(0,0)(fillxfill) sim={adjust=resize forwardNavigation} ty=BASE_APPLICATION fmt=TRANSLUCENT wanim=0x1030001
I/ViewRootImpl@3d3bb82[MainActivity](24178):   fl=81810100
I/ViewRootImpl@3d3bb82[MainActivity](24178):   pfl=16020040
I/ViewRootImpl@3d3bb82[MainActivity](24178):   vsysui=500
I/ViewRootImpl@3d3bb82[MainActivity](24178):   apr=LIGHT_STATUS_BARS
I/ViewRootImpl@3d3bb82[MainActivity](24178):   bhv=DEFAULT
I/ViewRootImpl@3d3bb82[MainActivity](24178):   fitSides= naviIconColor=0}
I/ViewRootImpl@3d3bb82[MainActivity](24178): updateBlastSurfaceIfNeeded mBlastBufferQueue=0xb40000760e473e90 isSameSurfaceControl=true
I/BLASTBufferQueue(24178): update, w= 1080 h= 2340 mName = ViewRootImpl@3d3bb82[MainActivity] mNativeObject= 0xb40000760e473e90 sc.mNativeObject= 0xb40000759e46cb30 format= -3 caller= android.view.ViewRootImpl.updateBlastSurfaceIfNeeded:2898 android.view.ViewRootImpl.relayoutWindow:9847 android.view.ViewRootImpl.performTraversals:3884 android.view.ViewRootImpl.doTraversal:3116 android.view.ViewRootImpl$TraversalRunnable.run:10885 android.view.Choreographer$CallbackRecord.run:1301 
I/ViewRootImpl@3d3bb82[MainActivity](24178): Relayout returned: old=(0,0,1080,2340) new=(0,0,1080,2340) req=(1080,2340)0 dur=5 res=0x1 s={true 0xb40000769e49fc60} ch=false seqId=0
I/ViewRootImpl@3d3bb82[MainActivity](24178): updateBoundsLayer: t = android.view.SurfaceControl$Transaction@9225765 sc = Surface(name=Bounds for - com.example.exclude_semantics/com.example.exclude_semantics.MainActivity@0)/@0x75e2c3a frame = 1
I/ViewRootImpl@3d3bb82[MainActivity](24178): mWNT: t=0xb4000075ce46e1b0 mBlastBufferQueue=0xb40000760e473e90 fn= 1 caller= android.view.ViewRootImpl.prepareSurfaces:2985 android.view.ViewRootImpl.performTraversals:4233 android.view.ViewRootImpl.doTraversal:3116 
I/ViewRootImpl@3d3bb82[MainActivity](24178): reportNextDraw android.view.ViewRootImpl.performTraversals:4438 android.view.ViewRootImpl.doTraversal:3116 android.view.ViewRootImpl$TraversalRunnable.run:10885 android.view.Choreographer$CallbackRecord.run:1301 android.view.Choreographer$CallbackRecord.run:1309 
I/BLASTBufferQueue(24178): [SurfaceView[com.example.exclude_semantics/com.example.exclude_semantics.MainActivity]@0#1](f:0,a:0) onFrameAvailable the first frame is available
D/SurfaceView@6c1211e(24178):  setAlpha: mUseAlpha = false alpha=1.0
D/SurfaceView@6c1211e(24178):  updateSurfaceAlpha: setUseAlpha() is not called, ignored.
I/ViewRootImpl@3d3bb82[MainActivity](24178): Setup new sync id=0
I/ViewRootImpl@3d3bb82[MainActivity](24178): Setting syncFrameCallback
I/ViewRootImpl@3d3bb82[MainActivity](24178): registerCallbacksForSync syncBuffer=false
I/ViewRootImpl@3d3bb82[MainActivity](24178): mWNT: t=0xb4000075ce479130 mBlastBufferQueue=0xb40000760e473e90 fn= 1 caller= android.view.ViewRootImpl.lambda$applyTransactionOnDraw$11$android-view-ViewRootImpl:12865 android.view.ViewRootImpl$$ExternalSyntheticLambda1.onFrameDraw:4 android.graphics.HardwareRenderer$FrameDrawingCallback.onFrameDraw:924 
I/ViewRootImpl@3d3bb82[MainActivity](24178): Received frameDrawingCallback syncResult=0 frameNum=1.
I/ViewRootImpl@3d3bb82[MainActivity](24178): Setting up sync and frameCommitCallback
D/SurfaceView@6c1211e(24178): updateSurfacePosition RenderWorker, frameNr = 1, position = [0, 0, 1080, 2196] surfaceSize = 1080x2196
I/SurfaceView@6c1211e(24178): uSP: rtp = Rect(0, 0 - 1080, 2196) rtsw = 1080 rtsh = 2196
I/SurfaceView@6c1211e(24178): onSSPAndSRT: pl = 0 pt = 0 sx = 1.0 sy = 1.0
I/SurfaceView@6c1211e(24178): aOrMT: ViewRootImpl@3d3bb82[MainActivity] t = android.view.SurfaceControl$Transaction@d6604e1 fN = 1 android.view.SurfaceView.-$$Nest$mapplyOrMergeTransaction:0 android.view.SurfaceView$SurfaceViewPositionUpdateListener.positionChanged:1537 android.graphics.RenderNode$CompositePositionUpdateListener.positionChanged:373 
I/ViewRootImpl@3d3bb82[MainActivity](24178): mWNT: t=0xb4000075ce479370 mBlastBufferQueue=0xb40000760e473e90 fn= 1 caller= android.view.SurfaceView.applyOrMergeTransaction:1455 android.view.SurfaceView.-$$Nest$mapplyOrMergeTransaction:0 android.view.SurfaceView$SurfaceViewPositionUpdateListener.positionChanged:1537 
I/BLASTBufferQueue(24178): [ViewRootImpl@3d3bb82[MainActivity]#0](f:0,a:0) onFrameAvailable the first frame is available
I/ViewRootImpl@3d3bb82[MainActivity](24178): Received frameCommittedCallback lastAttemptedDrawFrameNum=1 didProduceBuffer=true
D/OpenGLRenderer(24178): CFMS:: SetUp Pid : 24178    Tid : 24228
W/Parcel  (24178): Expecting binder but got null!
I/ViewRootImpl@3d3bb82[MainActivity](24178): onSyncComplete
I/ViewRootImpl@3d3bb82[MainActivity](24178): setupSync seqId=0 mSyncId=0 fn=1 caller=android.view.ViewRootImpl$$ExternalSyntheticLambda11.accept:6 android.window.SurfaceSyncer.lambda$setupSync$1$android-window-SurfaceSyncer:128 android.window.SurfaceSyncer$$ExternalSyntheticLambda1.accept:8 android.window.SurfaceSyncer$SyncSet.checkIfSyncIsComplete:382 android.window.SurfaceSyncer$SyncSet.markSyncReady:359 android.window.SurfaceSyncer.markSyncReady:151 android.view.ViewRootImpl.performTraversals:4503 
I/ViewRootImpl@3d3bb82[MainActivity](24178): reportDrawFinished seqId=0 mSyncId=-1 fn=1 mSurfaceChangedTransaction=0xb4000075ce46bdb0
I/ViewRootImpl@3d3bb82[MainActivity](24178): MSG_WINDOW_FOCUS_CHANGED 1 0
I/ViewRootImpl@3d3bb82[MainActivity](24178): mThreadedRenderer.initializeIfNeeded()#2 mSurface={isValid=true 0xb40000769e49fc60}
D/InputMethodManager(24178): startInputInner - Id : 0
I/InputMethodManager(24178): startInputInner - mService.startInputOrWindowGainedFocus
D/InputMethodManager(24178): startInputInner - Id : 0
D/InsetsController(24178): onStateChanged: InsetsState: {mDisplayFrame=Rect(0, 0 - 1080, 2340), mDisplayCutout=DisplayCutout{insets=Rect(0, 99 - 0, 0) waterfall=Insets{left=0, top=0, right=0, bottom=0} boundingRect={Bounds=[Rect(0, 0 - 0, 0), Rect(505, 0 - 575, 99), Rect(0, 0 - 0, 0), Rect(0, 0 - 0, 0)]} cutoutPathParserInfo={CutoutPathParserInfo{displayWidth=1080 displayHeight=2340 physicalDisplayWidth=1080 physicalDisplayHeight=2340 density={3.0} cutoutSpec={M 0,0 M 0,29 a 35,35 0 1,0 0,70 a 35,35 0 1,0 0,-70 Z} rotation={0} scale={1.0} physicalPixelDisplaySizeRatio={1.0}}}}, mRoundedCorners=RoundedCorners{[RoundedCorner{position=TopLeft, radius=96, center=Point(96, 96)}, RoundedCorner{position=TopRight, radius=96, center=Point(984, 96)}, RoundedCorner{position=BottomRight, radius=96, center=Point(984, 2244)}, RoundedCorner{position=BottomLeft, radius=96, center=Point(96, 2244)}]}  mRoundedCornerFrame=Rect(0, 0 - 1080, 2340), mPrivacyIndicatorBounds=PrivacyIndicatorBounds {static bounds=Rect(948, 0 - 1080, 99) rotation=0}, mSources= { InsetsSource: {mType=ITYPE_STATUS_BAR, mFrame=[0,0][1080,99], mVisible=true, mInsetsRoundedCornerFrame=false}, InsetsSource: {mType=ITYPE_NAVIGATION_BAR, mFrame=[0,2196][1080,2340], mVisible=true, mInsetsRoundedCornerFrame=false}, InsetsSource: {mType=ITYPE_LEFT_GESTURES, mFrame=[0,0][0,2340], mVisible=true, mInsetsRoundedCornerFrame=false}, InsetsSource: {mType=ITYPE_RIGHT_GESTURES, mFrame=[1080,0][1080,2340], mVisible=true, mInsetsRoundedCornerFrame=false}, InsetsSource: {mType=ITYPE_TOP_MANDATORY_GESTURES, mFrame=[0,0][1080,135], mVisible=true, mInsetsRoundedCornerFrame=false}, InsetsSource: {mType=ITYPE_BOTTOM_MANDATORY_GESTURES, mFrame=[0,2196][1080,2340], mVisible=true, mInsetsRoundedCornerFrame=false}, InsetsSource: {mType=ITYPE_LEFT_DISPLAY_CUTOUT, mFrame=[0,0][-100000,2340], mVisible=true, mInsetsRoundedCornerFrame=false}, InsetsSource: {mType=ITYPE_TOP_DISPLAY_CUTOUT, mFrame=[0,0][1080,99], mVisible=true, mInsetsRoundedCornerFrame=false}, InsetsSource: {mType=ITYPE_RIGHT_DISPLAY_CUTOUT, mFrame=[100000,0][1080,2340], mVisible=true, mInsetsRoundedCornerFrame=false}, InsetsSource: {mType=ITYPE_BOTTOM_DISPLAY_CUTOUT, mFrame=[0,100000][1080,2340], mVisible=true, mInsetsRoundedCornerFrame=false}, InsetsSource: {mType=ITYPE_TOP_TAPPABLE_ELEMENT, mFrame=[0,0][1080,99], mVisible=true, mInsetsRoundedCornerFrame=false}, InsetsSource: {mType=ITYPE_BOTTOM_TAPPABLE_ELEMENT, mFrame=[0,2196][1080,2340], mVisible=true, mInsetsRoundedCornerFrame=false}, InsetsSource: {mType=ITYPE_IME, mFrame=[0,0][0,0], mVisible=false, mInsetsRoundedCornerFrame=false} } host=com.example.exclude_semantics/com.example.exclude_semantics.MainActivity from=android.view.ViewRootImpl$ViewRootHandler.handleMessageImpl:6740
I/ViewRootImpl@3d3bb82[MainActivity](24178): MSG_WINDOW_FOCUS_CHANGED 0 0
I/ViewRootImpl@3d3bb82[MainActivity](24178): MSG_WINDOW_FOCUS_CHANGED 1 0
I/ViewRootImpl@3d3bb82[MainActivity](24178): mThreadedRenderer.initializeIfNeeded()#2 mSurface={isValid=true 0xb40000769e49fc60}
D/InputMethodManager(24178): startInputInner - Id : 0
I/InputMethodManager(24178): startInputInner - mService.startInputOrWindowGainedFocus
```

</details>


### Flutter Doctor output

<details open><summary>Doctor output</summary>

```console
Doctor summary (to see all details, run flutter doctor -v):
[✓] Flutter (Channel stable, 3.16.9, on macOS 14.2.1 23C71 darwin-x64, locale en-AU)
[✓] Android toolchain - develop for Android devices (Android SDK version 32.1.0-rc1)
[✓] Xcode - develop for iOS and macOS (Xcode 15.2)
[✓] Chrome - develop for the web
[✓] Android Studio (version 2022.2)
[✓] Connected device (5 available)
[✓] Network resources

• No issues found!
```

</details>