Adds a Listview tile select example (#99165)

diff --git a/examples/api/lib/widgets/scroll_view/listview_select.1.dart b/examples/api/lib/widgets/scroll_view/listview_select.1.dart
new file mode 100644
index 0000000..342ee36
--- /dev/null
+++ b/examples/api/lib/widgets/scroll_view/listview_select.1.dart
@@ -0,0 +1,239 @@
+// Copyright 2014 The Flutter Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Flutter code sample for ListTile selection in a ListView or GridView
+// Long press any ListTile to enable selection mode.
+
+import 'package:flutter/material.dart';
+
+void main() => runApp(const MyApp());
+
+class MyApp extends StatelessWidget {
+  const MyApp({Key? key}) : super(key: key);
+
+  static const String _title = 'Flutter Code Sample';
+
+  @override
+  Widget build(BuildContext context) {
+    return const MaterialApp(
+      title: _title,
+      home: ListTileSelectExample(),
+    );
+  }
+}
+
+class ListTileSelectExample extends StatefulWidget {
+  const ListTileSelectExample({Key? key}) : super(key: key);
+
+  @override
+  ListTileSelectExampleState createState() => ListTileSelectExampleState();
+}
+
+class ListTileSelectExampleState extends State<ListTileSelectExample> {
+  bool isSelectionMode = false;
+  final int listLength = 30;
+  late List<bool> _selected;
+  bool _selectAll = false;
+  bool _isGridMode = false;
+
+  @override
+  void initState() {
+    super.initState();
+    initializeSelection();
+  }
+
+  void initializeSelection() {
+    _selected = List<bool>.generate(listLength, (_) => false);
+  }
+
+  @override
+  void dispose() {
+    _selected.clear();
+    super.dispose();
+  }
+
+  @override
+  Widget build(BuildContext context) {
+    return Scaffold(
+        appBar: AppBar(
+          title: const Text(
+            'ListTile selection',
+          ),
+          leading: isSelectionMode
+              ? IconButton(
+                  icon: const Icon(Icons.close),
+                  onPressed: () {
+                    setState(() {
+                      isSelectionMode = false;
+                    });
+                    initializeSelection();
+                  },
+                )
+              : const SizedBox(),
+          actions: <Widget>[
+            if (_isGridMode)
+              IconButton(
+                icon: const Icon(Icons.grid_on),
+                onPressed: () {
+                  setState(() {
+                    _isGridMode = false;
+                  });
+                },
+              )
+            else
+              IconButton(
+                icon: const Icon(Icons.list),
+                onPressed: () {
+                  setState(() {
+                    _isGridMode = true;
+                  });
+                },
+              ),
+            if (isSelectionMode)
+              TextButton(
+                  child: !_selectAll
+                      ? const Text(
+                          'select all',
+                          style: TextStyle(color: Colors.white),
+                        )
+                      : const Text(
+                          'unselect all',
+                          style: TextStyle(color: Colors.white),
+                        ),
+                  onPressed: () {
+                    _selectAll = !_selectAll;
+                    setState(() {
+                      _selected =
+                          List<bool>.generate(listLength, (_) => _selectAll);
+                    });
+                  }),
+          ],
+        ),
+        body: _isGridMode
+            ? GridBuilder(
+                isSelectionMode: isSelectionMode,
+                selectedList: _selected,
+                onSelectionChange: (bool x) {
+                  setState(() {
+                    isSelectionMode = x;
+                  });
+                },
+              )
+            : ListBuilder(
+                isSelectionMode: isSelectionMode,
+                selectedList: _selected,
+                onSelectionChange: (bool x) {
+                  setState(() {
+                    isSelectionMode = x;
+                  });
+                },
+              ));
+  }
+}
+
+class GridBuilder extends StatefulWidget {
+  const GridBuilder({
+    Key? key,
+    required this.selectedList,
+    required this.isSelectionMode,
+    required this.onSelectionChange,
+  }) : super(key: key);
+
+  final bool isSelectionMode;
+  final Function(bool)? onSelectionChange;
+  final List<bool> selectedList;
+
+  @override
+  GridBuilderState createState() => GridBuilderState();
+}
+
+class GridBuilderState extends State<GridBuilder> {
+  void _toggle(int index) {
+    if (widget.isSelectionMode) {
+      setState(() {
+        widget.selectedList[index] = !widget.selectedList[index];
+      });
+    }
+  }
+
+  @override
+  Widget build(BuildContext context) {
+    return GridView.builder(
+        itemCount: widget.selectedList.length,
+        gridDelegate:
+            const SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 2),
+        itemBuilder: (_, int index) {
+          return InkWell(
+            onTap: () => _toggle(index),
+            onLongPress: () {
+              if (!widget.isSelectionMode) {
+                setState(() {
+                  widget.selectedList[index] = true;
+                });
+                widget.onSelectionChange!(true);
+              }
+            },
+            child: GridTile(
+                child: Container(
+              child: widget.isSelectionMode
+                  ? Checkbox(
+                      onChanged: (bool? x) => _toggle(index),
+                      value: widget.selectedList[index])
+                  : const Icon(Icons.image),
+            )),
+          );
+        });
+  }
+}
+
+class ListBuilder extends StatefulWidget {
+  const ListBuilder({
+    Key? key,
+    required this.selectedList,
+    required this.isSelectionMode,
+    required this.onSelectionChange,
+  }) : super(key: key);
+
+  final bool isSelectionMode;
+  final List<bool> selectedList;
+  final Function(bool)? onSelectionChange;
+
+  @override
+  State<ListBuilder> createState() => _ListBuilderState();
+}
+
+class _ListBuilderState extends State<ListBuilder> {
+  void _toggle(int index) {
+    if (widget.isSelectionMode) {
+      setState(() {
+        widget.selectedList[index] = !widget.selectedList[index];
+      });
+    }
+  }
+
+  @override
+  Widget build(BuildContext context) {
+    return ListView.builder(
+        itemCount: widget.selectedList.length,
+        itemBuilder: (_, int index) {
+          return ListTile(
+              onTap: () => _toggle(index),
+              onLongPress: () {
+                if (!widget.isSelectionMode) {
+                  setState(() {
+                    widget.selectedList[index] = true;
+                  });
+                  widget.onSelectionChange!(true);
+                }
+              },
+              trailing: widget.isSelectionMode
+                  ? Checkbox(
+                      value: widget.selectedList[index],
+                      onChanged: (bool? x) => _toggle(index),
+                    )
+                  : const SizedBox.shrink(),
+              title: Text('item $index'));
+        });
+  }
+}
diff --git a/examples/api/test/widgets/scrollview/listview_select_test.1.dart b/examples/api/test/widgets/scrollview/listview_select_test.1.dart
new file mode 100644
index 0000000..11087ce
--- /dev/null
+++ b/examples/api/test/widgets/scrollview/listview_select_test.1.dart
@@ -0,0 +1,74 @@
+// Copyright 2014 The Flutter Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+import 'package:flutter/material.dart';
+import 'package:flutter_api_samples/widgets/scroll_view/listview_select.1.dart'
+    as example;
+import 'package:flutter_test/flutter_test.dart';
+
+void main() {
+  testWidgets('long press ListTile should enable edit mode',
+      (WidgetTester tester) async {
+    await tester.pumpWidget(
+      const example.MyApp(),
+    );
+
+    final Finder listView = find.byType(ListView);
+    final Finder selectAllFinder = find.text('select all');
+    final Finder checkBoxFinder = find.byType(Checkbox);
+    expect(listView, findsWidgets);
+    expect(selectAllFinder, findsNothing);
+    expect(checkBoxFinder, findsNothing);
+    await tester.longPress(listView.first);
+    await tester.pump();
+    expect(selectAllFinder, findsOneWidget);
+    expect(checkBoxFinder, findsWidgets);
+  });
+
+  testWidgets('Pressing cross button should disable edit mode',
+      (WidgetTester tester) async {
+    await tester.pumpWidget(
+      const example.MyApp(),
+    );
+
+    final Finder listView = find.byType(ListView);
+    final Finder crossIconFinder = find.byIcon(Icons.close);
+    expect(listView, findsWidgets);
+    expect(crossIconFinder, findsNothing);
+
+    /// enable edit mode
+    await tester.longPress(listView.first);
+    await tester.pump();
+
+    expect(crossIconFinder, findsOneWidget);
+    await tester.tap(crossIconFinder);
+    await tester.pump();
+    final Finder selectAllFinder = find.text('select all');
+    expect(selectAllFinder, findsNothing);
+    expect(crossIconFinder, findsNothing);
+  });
+
+  testWidgets('tapping ListTile or checkBox should toggle ListTile state',
+      (WidgetTester tester) async {
+    await tester.pumpWidget(
+      const example.MyApp(),
+    );
+
+    final Finder listView = find.byType(ListView);
+    final Finder selectAllFinder = find.text('select all');
+    expect(listView, findsWidgets);
+
+    /// enable edit mode
+    await tester.longPress(listView.first);
+    await tester.pump();
+
+    final Finder checkBoxFinder = find.byType(Checkbox).first;
+    expect(selectAllFinder, findsOneWidget);
+    expect(checkBoxFinder, findsOneWidget);
+    expect(tester.widget<Checkbox>(checkBoxFinder).value, false);
+    await tester.tap(checkBoxFinder);
+    await tester.pump();
+    expect(tester.widget<Checkbox>(checkBoxFinder).value, true);
+  });
+}
diff --git a/packages/flutter/lib/src/widgets/scroll_view.dart b/packages/flutter/lib/src/widgets/scroll_view.dart
index ecc3029..a7f69bd 100644
--- a/packages/flutter/lib/src/widgets/scroll_view.dart
+++ b/packages/flutter/lib/src/widgets/scroll_view.dart
@@ -1010,6 +1010,13 @@
 /// example of how a caller might wire up basic item selection, see
 /// [ListTile.selected].
 ///
+/// {@tool dartpad}
+/// This example shows a custom implementation of [ListTile] selection in a [ListView] or [GridView].
+/// Long press any ListTile to enable selection mode.
+///
+/// ** See code in examples/api/lib/widgets/scroll_view/listview_select.1.dart **
+/// {@end-tool}
+///
 /// See also:
 ///
 ///  * [SingleChildScrollView], which is a scrollable widget that has a single
@@ -1700,6 +1707,13 @@
 /// ```
 /// {@end-tool}
 ///
+/// {@tool dartpad}
+/// This example shows a custom implementation of [ListTile] selection in a [GridView] or [ListView].
+/// Long press any ListTile to enable selection mode.
+///
+/// ** See code in examples/api/lib/widgets/scroll_view/listview_select.1.dart **
+/// {@end-tool}
+///
 /// See also:
 ///
 ///  * [SingleChildScrollView], which is a scrollable widget that has a single