This PR contributes to https://github.com/flutter/flutter/issues/155313
### Description
- Adds example for `WidgetStateProperty`
- Adds tests for `examples/api/lib/widgets/widget_state/widget_state_property.0.dart`
This PR is _almost_ able to close issue #89127.
Sadly, no `InheritedModel` or custom `RenderObject`s today; instead the [WidgetState operators](https://main-api.flutter.dev/flutter/widgets/WidgetStateOperators.html) have been restructured to support equality checks.
`WidgetStateProperty.fromMap()` is now capable of accurate equality checks, and all of the `.styleFrom()` methods have been refactored to use that constructor.
(Equality checks are still broken for `WidgetStateProperty.resolveWith()`, and any other non-`const` objects that implement the interface.)
<br><br>
credit for this idea goes to @justinmc: https://github.com/flutter/flutter/issues/89127#issuecomment-2313187703
This PR is to update the token version to v6.1.
* This version fixes https://github.com/flutter/flutter/issues/153271
* Change the chip default border color from `ColorScheme.outline` to `ColorScheme.outlineVariant`. The Chips' border color is softened to improve visual hierarchy between chips and buttons
Contributes to https://github.com/flutter/flutter/issues/130459
It adds a test for
- `examples/api/lib/rendering/sliver_grid/sliver_grid_delegate_with_fixed_cross_axis_count.0.dart`
- `examples/api/lib/rendering/sliver_grid/sliver_grid_delegate_with_fixed_cross_axis_count.1.dart`
I also fixed a mistake in the documentation
This PR adds a new constructor to the RefreshIndicator's class, which is `noSpinner`.
The purpose of this new constructor is to create a RefreshIndicator that doesn't show a spinner when the user arms it by pulling.
The work is based on a partial that is here: https://github.com/flutter/flutter/pull/133507
I addressed the following issues reported in the PR above:
- in the example for `noSpinner`, arming the RefreshIndicator now shows a CircularProgressIndicator, instead of just printing text to the console;
- added a test for the new example;
- added a doc comment on the new constructor;
Fixes https://github.com/flutter/flutter/issues/132775
CustomScrollViewExampleApp
Part of https://github.com/flutter/flutter/issues/130459
The test is checking:
- if all crucial Widgets are initially visible
- if IconButton click will expand existing SliverList
- if IconButton click and mouse scroll will reveal additional SliverList
I've updated these two examples to support state restoration of the navigation stack and verified that they work with predictive back in the tests. This was motivated by a worry that users are not properly setting up their navigation and that our examples are misleading them in the name of simplicity.
Contributes to https://github.com/flutter/flutter/issues/130459
It adds a test for
- `examples/api/lib/widgets/single_child_scroll_view/single_child_scroll_view.0.dart`
- `examples/api/lib/widgets/single_child_scroll_view/single_child_scroll_view.1.dart`
I also fixed a mistake in the documentation
Reverts: flutter/flutter#152487
Initiated by: gmackall
Reason for reverting: I forgot that I need to override the compileSdkVersion in the AGP 8.0 [instance of this test](ef9cd32f5a/dev/devicelab/bin/tasks/android_java17_dependency_smoke_tests.dart (L19))
Original PR Author: gmackall
Reviewed By: {reidbaker}
This change reverts the following previous change:
Updates `compileSdk`, `targetSdk`, and `ndk` versions (former 2 to latest, latter to the version of the ndk we are hosting on CIPD).
Summary of changes:
- Updates mentioned template values
- `compileSdk` 35 requires AGP 8.0+, so updated to 8.1 in many places.
- This also necessitated Gradle upgrades in most places
- This also necessitated moving the `package` xml attribute to the AGP `namespace` field in a couple places (test + template).
- Some tests use the output of `flutter create` but then use intentionally lower AGP versions. [I downgraded the `compileSdk` in these tests.](fee34fd61a)
- [Stopped lockfile generation](82324a2570) script from hitting the `hello_world` example because it uses `.kts` gradle files.
- One test needed [some Gradle options we had already added to templates](6aa187b4b6).
Updates `compileSdk`, `targetSdk`, and `ndk` versions (former 2 to latest, latter to the version of the ndk we are hosting on CIPD).
Summary of changes:
- Updates mentioned template values
- `compileSdk` 35 requires AGP 8.0+, so updated to 8.1 in many places.
- This also necessitated Gradle upgrades in most places
- This also necessitated moving the `package` xml attribute to the AGP `namespace` field in a couple places (test + template).
- Some tests use the output of `flutter create` but then use intentionally lower AGP versions. [I downgraded the `compileSdk` in these tests.](fee34fd61a)
- [Stopped lockfile generation](82324a2570) script from hitting the `hello_world` example because it uses `.kts` gradle files.
- One test needed [some Gradle options we had already added to templates](6aa187b4b6).
This PR fixes#92525 and introduces the following changes according to [latest iOS HIG](https://developer.apple.com/design/human-interface-guidelines/buttons#iOS-iPadOS):
- `CupertinoButton` now has a `size` property (type `enum CupertinoButtonSize`, values sm/md/lg, default `lg`) that allows the devs to apply new iOS 15+ button styles
- Previously `CupertinoButton` had a larger padding when no background color was specified. With the new HIG, that is no longer the case
- `CupertinoButton` now has a `.tinted` constructor that renders a translucent background (transparency % is brightness-dependent) and uses a different foreground color compared to `.filled`
- `CupertinoButton` now uses the `actionTextStyle` TextStyle from the given theme
- `CupertinoButton`'s child IconTheme's size will always be x1.2 the given TextStyle's size
- `CupertinoTextThemeData` now has a `actionSmallTextStyle` property to use with small buttons (including a default `_kDefaultActionSmallTextStyle` TextStyle)
Preview & example:

> **NOTE**: there is a discrepancy in dark mode button foreground color between the default CupertinoTheme and the HIG. A separate issue will be opened for this.
~EDIT: issue reported here https://github.com/flutter/flutter/issues/152846~
EDIT2: fixed by #153039 !

## Example
```dart
import 'package:flutter/cupertino.dart';
const Widget body = Row(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Icon(
CupertinoIcons.play_fill,
),
Text("Play"),
],
);
void main() =>
runApp(
CupertinoApp(
home: Container(
child: Wrap(
direction: Axis.horizontal,
children: <Widget>[
// header
Text(''),
Text('Plain'),
Text('Grey'),
Text('Tinted'),
Text('Filled'),
// small
Text('Small'),
CupertinoButton(
child: body,
onPressed: () {},
size: CupertinoButtonSize.small,
),
CupertinoButton.tinted(
child: body,
onPressed: () {},
size: CupertinoButtonSize.small,
color: CupertinoColors.systemGrey,
),
CupertinoButton.tinted(
child: body,
onPressed: () {},
size: CupertinoButtonSize.small,
),
CupertinoButton.filled(
child: body,
onPressed: () {},
size: CupertinoButtonSize.small,
),
// medium
Text('Medium'),
CupertinoButton(
child: body,
onPressed: () {},
size: CupertinoButtonSize.medium,
),
CupertinoButton.tinted(
child: body,
onPressed: () {},
size: CupertinoButtonSize.medium,
color: CupertinoColors.systemGrey,
),
CupertinoButton.tinted(
child: body,
onPressed: () {},
size: CupertinoButtonSize.medium,
),
CupertinoButton.filled(
child: body,
onPressed: () {},
size: CupertinoButtonSize.medium,
),
// large
Text('Large'),
CupertinoButton(
child: body,
onPressed: () {},
size: CupertinoButtonSize.large,
),
CupertinoButton.tinted(
child: body,
onPressed: () {},
color: CupertinoColors.systemGrey,
size: CupertinoButtonSize.large,
),
CupertinoButton.tinted(
child: body,
onPressed: () {},
size: CupertinoButtonSize.large,
),
CupertinoButton.filled(
child: body,
onPressed: () {},
size: CupertinoButtonSize.large,
),
].map((Widget w) => SizedBox(width: 110, height: 70, child: Center(child: w))).toList(),
),
)
),
);
```
*List which issues are fixed by this PR. You must list at least one issue. An issue is not required if the PR fixes something trivial like a typo.*
*If you had to change anything in the [flutter/tests] repo, include a link to the migration guide as per the [breaking change policy].*
Move `scroll_direction.0_test.dart` & `growth_direction.0_test.dart` to same directory structure as the example files.
Tests were already present, only had to move them & remove the entries from the missing tests.
Part of #130459
This PR is aimed at (1) reducing the private API surface of _MenuAnchorState to make migration into RawMenuAnchor simpler, and (2) fixing focus-related bugs.
Directional focus handling was moved from MenuAnchor (_MenuDirectionalFocusAction, _MenuNextFocusAction, and _MenuPreviousFocusAction) into SubmenuButton (_SubmenuDirectionalFocusAction). MenuAnchor now behaves similarly to a flat FocusScope, which makes it easier to customize. A future PR will ideally expose or remove the remaining internals (_lastItemFocusNode, _firstItemFocusNode, _isRoot, etc). All previous framework tests are passing, and additional tests were added for fixes (MenuAnchor tab traversal, reopened menus not being focusable), and to test MenuAnchor focus behavior separately from MenuBar.
However, [one example test](https://github.com/flutter/flutter/pull/150950/files#diff-a33fa01b59d280784e7c8ed6b704bd005cde95b7d3b649dc82fd58530061a09d) had to be changed. I'm not sure why the previous example test was working to begin with, as submenu buttons are supposed to open on focus, but this behavior was not observed in the original test.
Fixes https://github.com/flutter/flutter/issues/144381, https://github.com/flutter/flutter/issues/150334.
One added feature is the ability to move between top-level horizontal submenus if a horizontal movement is made on a vertical menu item that has no children in the movement direction. This behavior was observed on Google Docs, MacOS, and various other menu systems I encountered.
https://github.com/flutter/flutter/assets/59215665/04a42b8a-cc9e-4a50-9d0c-6f2d784cfc78
Contributes to https://github.com/flutter/flutter/issues/130459
It adds a test for
- `examples/api/lib/material/scaffold/scaffold_messenger_state.show_snack_bar.0.dart`
- `examples/api/lib/material/scaffold/scaffold_messenger_state.show_material_banner.0.dart`
Currently, there are 21 `.resolveWith()` calls in example files.
This pull request changes 11 of them to use the new `.fromMap()` constructor. (Seven of them are now `const`!)
```dart
ListTile(
iconColor: WidgetStateColor.fromMap(<WidgetStatesConstraint, Color>{
WidgetState.disabled: Colors.red,
WidgetState.selected: Colors.green,
WidgetState.any: Colors.black,
}),
// The same can be achieved using the .resolveWith() constructor.
// The text color will be identical to the icon color above.
textColor: WidgetStateColor.resolveWith((Set<WidgetState> states) {
if (states.contains(WidgetState.disabled)) {
return Colors.red;
}
if (states.contains(WidgetState.selected)) {
return Colors.green;
}
return Colors.black;
}),
),
```
Contributes to https://github.com/flutter/flutter/issues/130459
It adds a test for
- `examples/api/lib/material/search_anchor/search_anchor.1.dart`
- `examples/api/lib/material/search_anchor/search_anchor.2.dart`
Contributes to https://github.com/flutter/flutter/issues/130459
It adds a test for
- `examples/api/lib/material/scaffold/scaffold_messenger.0.dart`
- `examples/api/lib/material/scaffold/scaffold_messenger.of.0.dart`
- `examples/api/lib/material/scaffold/scaffold_messenger.of.1.dart`
This PR contains:
- 3 instances of `colorScheme.background` â `colorScheme.surface`
- and a whole bunch of `MaterialState` â `WidgetState`
As of yet, no changes have been made to example test files or the [examples/api/lib/material/material_state/](0b2a8e589e/examples/api/lib/material/material_state) directory.
(related: #151373)
This PR is making the `CupertinoNavigationBar` and `CupertinoSliverNavigationBar` appear transparent as long as the content is not scrolled under them, so they look like standard iOS apps nav bars.
https://github.com/flutter/flutter/assets/423393/eee2700b-2a91-4577-922c-6163d47cb357https://github.com/flutter/flutter/assets/423393/3847f2b5-0dac-4d5e-aa6f-03c1d2893e30
<details>
<summary>Demo app code</summary>
```dart
import 'package:flutter/cupertino.dart';
/// Flutter code sample for [CupertinoTabScaffold].
void main() => runApp(const TabScaffoldApp());
class TabScaffoldApp extends StatefulWidget {
const TabScaffoldApp({super.key});
@override
State<TabScaffoldApp> createState() => _TabScaffoldAppState();
}
class _TabScaffoldAppState extends State<TabScaffoldApp> {
Brightness _brightness = Brightness.light;
@override
Widget build(BuildContext context) {
return CupertinoApp(
theme: CupertinoThemeData(brightness: _brightness),
home: TabScaffoldExample(
brightness: _brightness, onBrightnessToggle: _toggleBrightness),
);
}
void _toggleBrightness() {
setState(() {
_brightness =
_brightness == Brightness.light ? Brightness.dark : Brightness.light;
});
}
}
class TabScaffoldExample extends StatefulWidget {
const TabScaffoldExample(
{required this.brightness, required this.onBrightnessToggle, super.key});
final VoidCallback onBrightnessToggle;
final Brightness brightness;
@override
State<TabScaffoldExample> createState() => _TabScaffoldExampleState();
}
class _TabScaffoldExampleState extends State<TabScaffoldExample> {
@override
Widget build(BuildContext context) {
return CupertinoTabScaffold(
tabBar: CupertinoTabBar(
items: const <BottomNavigationBarItem>[
BottomNavigationBarItem(
icon: Icon(CupertinoIcons.home),
label: 'Home',
),
BottomNavigationBarItem(
icon: Icon(CupertinoIcons.search_circle_fill),
label: 'Explore',
),
BottomNavigationBarItem(
icon: Icon(CupertinoIcons.person_fill),
label: 'Profile',
),
BottomNavigationBarItem(
icon: Icon(CupertinoIcons.settings_solid),
label: 'Settings',
),
],
),
tabBuilder: (BuildContext context, int index) {
return CupertinoTabView(
builder: (BuildContext context) {
return CupertinoPageScaffold(
backgroundColor: index == 3
? CupertinoColors.secondarySystemBackground
.resolveFrom(context)
: null,
child: CustomScrollView(
slivers: [
CupertinoSliverNavigationBar(
largeTitle: Text('Tab $index'),
initiallyTransparent: index != 2,
trailing: CupertinoButton(
padding: EdgeInsets.zero,
onPressed: widget.onBrightnessToggle,
child: Icon(
widget.brightness == Brightness.light
? CupertinoIcons.moon_stars
: CupertinoIcons.sun_max,
),
),
),
SliverSafeArea(
top: false,
sliver: SliverList.list(
children: [
CupertinoButton(
child: const Text('Next page'),
onPressed: () {
Navigator.of(context).push(
CupertinoPageRoute<void>(
builder: (BuildContext context) {
return CupertinoPageScaffold(
navigationBar: CupertinoNavigationBar(
middle: Text('Inner page of tab $index'),
),
child: ListView(
children: [
Center(
child: CupertinoButton(
child: const Text('Back'),
onPressed: () {
Navigator.of(context).pop();
},
),
),
if (index == 0) const _LongList(),
const SizedBox(height: 20),
],
),
);
},
),
);
},
),
if (index == 1) const _LongList(),
const SizedBox(height: 20),
],
),
),
],
),
);
},
);
},
);
}
}
class _LongList extends StatelessWidget {
const _LongList();
@override
Widget build(BuildContext context) {
return Column(
children: [
for (int i = 0; i < 50; i++) ...[
CupertinoListTile(
leading: const Icon(CupertinoIcons.book),
title: Text('Bookstore item $i'),
),
],
],
);
}
}
```
</details>
This is the continuation of https://github.com/flutter/flutter/pull/142439.
I tried to keep the simplest API possible, so it's only introducing a new `automaticBackgroundVisibility` boolean parameter.
In the implementation I had to use the `CupertinoPageScaffold` background color to make it look transparent instead of a 0 opacity, because of issues with route transitions.
I used an `InheritedWidget` so the nav bar is always getting the right background color from the parent scaffold, whether it is overridden or not. It would probably be better to make the inherited widget private but we'd need to move all the nav bar code to the same file as the scaffold, so for now I've just hidden it from the export. Let me know if it is okay to do that.
This PR is not dealing with the bottom tab bar, because the same [straightforward approach](dde8ec6dc7) doesn't work here. The problem is that the scroll notification is sent only when the scroll view is created or updated, so it doesn't work if one pushes a screen and navigates back.
Issues:
- #78607
- #60411
A relatively elaborate PinnedSliverHeader example which creates an app bar that's similar to the one that appears in the iOS Settings app. In this example the pinned header starts out transparent and the first item in the list serves as the app's "Settings" title. When the title item has been scrolled completely behind the pinned header, the header animates its opacity from 0 to 1 and its (centered) "Settings" title appears. The fact that the header's opacity depends on the height of the title item - which is unknown until the list has been laid out - necessitates monitoring its SliverConstraints.scrollExtent from a scroll NotificationListener.
https://github.com/flutter/flutter/assets/1377460/539e2591-d0d7-4508-8ce8-4b8f587d7648
A sliver that shows its [child] when the user scrolls forward and hides it when the user scrolls backwards. Similar headers can be found in Google Photos and Facebook.
This sliver is preferable to the general purpose SliverPersistentHeader for its relatively narrow use case because there's no need to create a SliverPersistentHeaderDelegate or to predict the header's size.
https://github.com/flutter/flutter/assets/1377460/82b67dfb-5d38-4adf-9415-fc8527d0eb9f
Adds a new ScrollNotificationEnd example that demonstrates how to trigger an auto-scroll based on an individual sliver's `SliverConstraints` and `SliverGeometry`.
Then new example auto-scrolls one special "aligned item" sliver to the top or bottom of the viewport, whenever it's partially visible (because it overlaps the top or bottom of the viewport). This example differs from the existing ScrollEndNotification example because the layout of the to-be aligned sliver is retrieved from its `RenderSliver` via a
GlobalKey. The new example does not rely on all of the list items having the same extent.
This PR removes the usage of Material widgets from unit tests of `CupertinoAlertDialog`. Other than it being just wrong, it also introduces bad behavior, such as the scroll view can't be overscrolled so that the overscroll behavior can't be tested.
* Since there are no longer M2 or M3 variants of tests, I straight up rewrote the unit tests for "default look" with similar tests as those of `CupertinoActionSheet` ([here](https://github.com/flutter/flutter/blob/master/packages/flutter/test/cupertino/action_sheet_test.dart#L21))
This PR also replaces `showCupertinoModalPopup` with `showCupertinoDialog` in `CupertinoAlertDialog`'s example code. The former should only be used by `CupertinoActionSheet`, which has a different animation from the correct `showCupertinoDialog`.
Reverts: flutter/flutter#150733
Initiated by: gmackall
Reason for reverting: This breaks apps that use plugins that use `compileSdk` 31, some of which we use in our postsubmit (so it blocks the tree).
Original PR Author: gmackall
Reviewed By: {jason-simmons}
This change reverts the following previous change:
Manual engine roll to https://github.com/flutter/engine/pull/53532, because the roll requires lockfile generation.
Reverts: flutter/flutter#150481
Initiated by: cbracken
Reason for reverting: Surprisingly, the following test seems to be consistently failing on Windows after the addition of this test:
```
flutter/packages/flutter/test/widgets/sliver_tree_test.dart: .toggleNodeWith, onNodeToggle
```
Original PR Author: ValentinVignal
Reviewed By: {TahaTesser, bleroux}
This change reverts the following previous change:
Contributes to https://github.com/flutter/flutter/issues/130459
It adds a test for
- `examples/api/lib/material/text_form_field/text_form_field.1.dart`
Removes these two discontinued plugins from `dev/integration_tests/flutter_gallery`
[`device_info`](https://pub.dev/packages/device_info):
Apparently the video playback doesn't work on iOS simulators (I wasn't able to verify this, as I don't have an iOS simulator installed). I removed the guard against running on those simulators, and replaced with a note in the README.
[`connectivity`](https://pub.dev/packages/connectivity):
This plugin was used to play the bee video from the network. I changed the demo so that the bee video is instead also played from an asset (like its friend the butterfly), and then removed the use of the plugin.
Unblocks the re-land of https://github.com/flutter/engine/pull/53462 (itself a reland ð), because of https://github.com/flutter/flutter/pull/150465#issuecomment-2181403712.
Add tests for `InputDecoration` API example as part of #130459. Updates examples that use the deprecated MaterialState to use WidgetState. Tests files: `input_decoration.0.dart`, `input_decoration.1.dart`, `input_decoration.2.dart`, `input_decoration.3.dart`, `input_decoration.widget_state.0.dart`, `input_decoration.widget_state.1.dart`, `input_decoration.prefix_icon_constraints.0.dart`, `input_decoration.suffix_icon_constraints.0.dart`, and `input_decoration.label.0.dart`
Introducing the `forceErrorText` property to both `FormField` and `TextFormField`. With this addition, we gain the capability to trigger an error state and provide an error message without invoking the `validator` method.
While the idea of making the `Validator` method work asynchronously may be appealing, it could introduce significant complexity to our current form field implementation. Additionally, this approach might not be suitable for all developers, as discussed by @justinmc in this [comment](https://github.com/flutter/flutter/issues/56414#issuecomment-624960263).
This PR try to address this issue by adding `forceErrorText` property allowing us to force the error to the `FormField` or `TextFormField` at our own base making it possible to preform some async operations without the need for any hacks while keep the ability to check for errors if we call `formKey.currentState!.validate()`.
Here is an example:
<details> <summary>Code Example</summary>
```dart
import 'package:flutter/material.dart';
void main() {
runApp(
const MaterialApp(home: MyHomePage()),
);
}
class MyHomePage extends StatefulWidget {
const MyHomePage({
super.key,
});
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
final key = GlobalKey<FormState>();
String? forcedErrorText;
Future<void> handleValidation() async {
// simulate some async work..
await Future.delayed(const Duration(seconds: 3));
setState(() {
forcedErrorText = 'this username is not available.';
});
// wait for build to run and then check.
//
// this is not required though, as the error would already be showing.
WidgetsBinding.instance.addPostFrameCallback((_) {
print(key.currentState!.validate());
});
}
@override
Widget build(BuildContext context) {
print('build');
return Scaffold(
floatingActionButton: FloatingActionButton(onPressed: handleValidation),
body: Form(
key: key,
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Padding(
padding: const EdgeInsets.symmetric(horizontal: 30),
child: TextFormField(
forceErrorText: forcedErrorText,
),
),
],
),
),
),
);
}
}
```
</details>
Related to #9688 & #56414.
Happy to hear your thoughts on this.
The widget under test already contains a MaterialApp, so there's no need to wrap it again with one in the test. In fact, the additional MaterialApp could hide problems in the widget under test.
## Description
This fixes the `ColorScheme` example to actually work. The test had wrapped the app in an additional `MaterialApp`, which allowed the tests to work, but the real problem was using a `context` that was outside the `MaterialApp` to open the bottom sheet, which caused an exception when you actually try to run it interactively.
This fixes the example and the test.
## Tests
- Fixed the test to not artificially add a second `MaterialApp`.
Contributes to https://github.com/flutter/flutter/issues/130459
It adds a test for
- `examples/api/lib/material/scaffold/scaffold.drawer.0.dart`
- `examples/api/lib/material/scaffold/scaffold.end_drawer.0.dart`
A sliver that is pinned to the start of its `CustomScrollView` and reacts to scrolling by resizing between the intrinsic sizes of its min and max extent prototypes.
The minimum and maximum sizes of this sliver are defined by `minExtentPrototype` and `maxExtentPrototype`, a pair of widgets that are laid out once. You can use `SizedBox` widgets to define the size limits.
This sliver is preferable to the general purpose `SliverPersistentHeader` for its relatively narrow use case because there's no need to create a `SliverPersistentHeaderDelegate` or to predict the header's minimum or maximum size.
The sample shows how this sliver's two extent prototype properties can be used to create a resizing header whose minimum and maximum sizes match small and large configurations of the same header widget.
https://github.com/flutter/flutter/assets/1377460/fa7ced98-9d92-4d13-b093-50392118c213
Related sliver utility PRs: https://github.com/flutter/flutter/pull/143538, https://github.com/flutter/flutter/pull/143196, https://github.com/flutter/flutter/pull/127340.
This PR adds `AnimatedList.separated`. A widget like an AnimatedList with animated separators. `animated_list_separated.0.dart` extends `animated_list.0.dart` to work with `AnimatedList.separated`
Related issue: https://github.com/flutter/flutter/issues/48226
The scroll notification events reported for a press-drag-release gesture within a scrollable on a touch screen device begin with a `ScrollStartNotification`, followed by a series of `ScrollUpdateNotifications`, and conclude with a `ScrollEndNotification`. This protocol can be used to defer work until an interactive scroll gesture ends. For example, you might defer updating a scrollable's contents via network requests until the scroll has ended, or you might want to automatically auto-scroll at that time.
In the example that follows the CustomScrollView automatically scrolls so that the last partially visible fixed-height item is completely visible when the scroll gesture ends. Many iOS applications do this kind of thing. It only makes sense to auto-scroll when the user isn't actively dragging the scrollable around.
It's easy enough to do this by reacting to a ScrollEndNotifcation by auto-scrolling to align the last fixed-height list item ([source code](https://gist.github.com/HansMuller/13e2a7adadc9afb3803ba7848b20c410)).
https://github.com/flutter/flutter/assets/1377460/a6e6fc77-6742-4f98-81ba-446536535f73
Dragging the scrollbar thumb in a desktop application is a similar user gesture. Currently it's not possible to defer work or auto-scroll (or whatever) while the scrollable is actively being dragged via the scrollbar thumb because each scrollbar thumb motion is mapped to a scroll start - scroll update - scroll end series of notifications. On a desktop platform, the same code behaves quite differently when the scrollbar thumb is dragged.
https://github.com/flutter/flutter/assets/1377460/2593d8a3-639c-407f-80c1-6e6f67fb8c5f
The stream of scroll-end events triggers auto-scrolling every time the thumb moves. From the user's perspective this feels like a losing struggle.
One can also detect the beginning and end of a touch-drag by listening to the value of a ScrollPosition's `isScrollingNotifier`. This approach suffers from a similar problem: during a scrollbar thumb-drag, the `isScrollingNotifier` value isn't updated at all.
This PR refactors the RawScrollbar implementation to effectively use a ScrollDragController to manage scrolls caused by dragging the scrollbar's thumb. Doing so means that dragging the thumb will produce the same notifications as dragging the scrollable on a touch device.
Now desktop applications can choose to respond to scrollbar thumb drags in the same that they respond to drag scrolling on a touch screen. With the changes included here, the desktop or web version of the app works as expected, whether you're listing to scroll notifications or the scroll position's `isScrollingNotifier`.
https://github.com/flutter/flutter/assets/1377460/67435c40-a866-4735-a19b-e3d68eac8139
This PR also makes the second [ScrollPosition API doc example](https://api.flutter.dev/flutter/widgets/ScrollPosition-class.html#cupertino.ScrollPosition.2) work as expected when used with the DartPad that's part of API doc page.
Desktop applications also see scroll start-update-end notifications due to the mouse wheel. There is no touch screen analog for the mouse wheel, so an application that wanted to enable this kind of auto-scrolling alignment would have to include a heuristic that dealt with the sequence of small scrolls triggered by the mouse wheel. Here's an example of that: [source code](https://gist.github.com/HansMuller/ce5c474a458f5f4bcc07b0d621843165). This version of the app does not auto-align in response to small changes, wether they're triggered by dragging the scrollbar thumb of the mouse wheel.
Related sliver utility PRs: https://github.com/flutter/flutter/pull/143538, https://github.com/flutter/flutter/pull/143196, https://github.com/flutter/flutter/pull/143325.
The current MenuAnchor example in the API Docs is comprehensive and complicated for beginners. I have added a simple bare bone example without shortcuts, enums, etc in examples/api/lib/material/menu_anchor/ as `menu_anchor.3.dart`. The example is contributed by @mafreud
Fixes https://github.com/flutter/flutter/issues/148104
Manual recreation of https://github.com/flutter/flutter/pull/148911
Entire PR is just the output of
```
flutter update-packages --force-upgrade
```
followed by (run from the root of the flutter repo)
```
find . -type d -name 'android' | dart dev/tools/bin/generate_gradle_lockfiles.dart --no-gradle-generation --no-exclusion
```
Adds tests for `relative_positioned_transition`, `positioned_transition`, `sliver_fade_transition`, `align_transition`, `animated_builder`, `rotation_transition`, `animated_widget`, `slide_transition`, `listenable_builder`, `scale_transition`, `default_text_style_transition`, `decorated_box_transition`, `size_transition` api examples. Makes double type in the `align_transition` example explicit.
A test for `fade_transition` is already in currently open #148178.
Part of #130459.
Adds tests to the last two Snack Bar examples as part of #130459. Makes the [last example](https://api.flutter.dev/flutter/material/SnackBar-class.html#material.SnackBar.3) more usable through the use of standard widgets and visual hierarchy. Constraints on options that are not required by the SnackBar contract have been removed (Overflow threshold works on fixed SnackBars).
Contributes to https://github.com/flutter/flutter/issues/130459
It adds test for
- `examples/api/lib/material/scaffold/scaffold.0.dart`
- `examples/api/lib/material/scaffold/scaffold.2.dart`
It also modifies the `scaffold.1_test.dart` because the only difference with scaffold 0 is the background color, so I figured the test should include it
This PR contributes to https://github.com/flutter/flutter/issues/130459
### Description
- Updates `examples/api/lib/widgets/restoration_properties/restorable_value.0.dart` to meet the latest API examples structure
- Adds tests for `examples/api/lib/widgets/restoration_properties/restorable_value.0.dart`
This PR contributes to https://github.com/flutter/flutter/issues/130459
### Description
- Updates `examples/api/lib/widgets/actions/actions.0.dart` to meet the latest API examples structure
- Adds tests for `examples/api/lib/widgets/actions/actions.0.dart`
### fixes#136139
<br>
<details open> <summary><b>getting sentimental in the PR description</b> (click to collapse)<br><br></summary>
The past 7 months have been quite the journeyâI made some huge blunders and some huge accomplishmentsâa very fun time overall.
I really appreciate the people who took the time to perform code review for my refactoring shenanigans: **christopherfujino**, **andrewkolos**, **LongCatIsLooong**, **gspencergoog**, **loic-sharma**, **Piinks**, **bernaferrari**, **bartekpacia**, **bleroux**, **kevmoo**, **rakudrama**, **XilaiZhang**, **QuncCccccc**, **MominRaza**, and **victorsanni**.
And a huge shoutout to 2 individuals:
- @justinmc, for offering to sponsor me for commit access (words could not describe my excitement)
- @goderbauer, for being super duper proactive and consistent with code review
<br>
</details>
This pull request makes 13 "switch statements â switch expressions" PRs in total, reducing the LOC in this repo by **1,974**!
From now on, I'll make sure to request a test exemption for each refactoring PR ð
This PR contributes to https://github.com/flutter/flutter/issues/130459
### Description
- Updates `examples/api/lib/widgets/shared_app_data/shared_app_data.0.dart` to meet latest API examples structure
- Updates `examples/api/lib/widgets/shared_app_data/shared_app_data.1.dart` to meet latest API examples structure
- Adds tests for `examples/api/lib/widgets/shared_app_data/shared_app_data.0.dart`
- Adds tests for `examples/api/lib/widgets/shared_app_data/shared_app_data.1.dart`
This PR contributes to https://github.com/flutter/flutter/issues/130459
### Description
- Corrects the name for `examples/api/test/widgets/shortcuts/logical_key_set.0_test.dart` test file
- Update tests for `examples/api/lib/widgets/shortcuts/logical_key_set.0.dart`
PR #147801 introduced some convenient `AnimationStatus` getters, but I just realized that `AnimationController` now has 2 getters for the same thing: `isAnimating` and `isRunning`.
The intent of this pull request is to correct that mistake, and implement the getters in the appropriate places.
This PR contributes to https://github.com/flutter/flutter/issues/130459
### Description
- Updates `examples/api/lib/material/tab_controller/tab_controller.1.dart` to properly remove the listener from the `TabController`
- Adds tests for `examples/api/lib/material/tab_controller/tab_controller.1.dart`
This PR contributes to https://github.com/flutter/flutter/issues/130459
### Description
- Adds disposal of the `CurvedAnimation` in `examples/api/test/widgets/transitions/fade_transition.0.dart`
- Adds tests for `examples/api/lib/widgets/transitions/fade_transition.0.dart`
This PR contributes to https://github.com/flutter/flutter/issues/130459
### Description
- Adds tests for `examples/api/lib/material/scaffold/scaffold.of.0.dart`
- Adds tests for `examples/api/lib/material/scaffold/scaffold.of.1.dart`
*Use `super.key` instead of manually passing the `Key` parameter using super(key: key) in the constructors.*
Since if you create a widget the new default will use `super.key` instead of `Key? key : super(key: key)` this small change is to maintain the consistency, it has no semantic change
also there are some other places that might need to be updated:

this file for example generate l10n project and it has all the dart code as String, it might have tests that validate the output somewhere that I might miss, also there are some other places like the `_Segment` class where it require `ValueKey` instead if `Key` so I didn't update them (even though it's possible)
Reverts: flutter/flutter#148238
Initiated by: zanderso
Reason for reverting: Failures in post submit https://logs.chromium.org/logs/flutter/buildbucket/cr-buildbucket/8748025189669617649/+/u/run_test.dart_for_web_canvaskit_tests_shard_and_subshard_3/stdout
Original PR Author: justinmc
Reviewed By: {hellohuanlin}
This change reverts the following previous change:
Reland of https://github.com/flutter/flutter/pull/143002, which was reverted in https://github.com/flutter/flutter/pull/148237 due to unresolved docs references. Not sure why those weren't caught in presubmit.
```
dartdoc:stdout: Generating docs for package flutter...
dartdoc:stderr: error: unresolved doc reference [TextInput.showSystemContextMenu]
dartdoc:stderr: from widgets.MediaQueryData.supportsShowingSystemContextMenu: (file:///b/s/w/ir/x/w/flutter/packages/flutter/lib/src/widgets/media_query.dart:579:14)
dartdoc:stderr: in documentation inherited from widgets.MediaQueryData.supportsShowingSystemContextMenu: (file:///b/s/w/ir/x/w/flutter/packages/flutter/lib/src/widgets/media_query.dart:579:14)
dartdoc:stderr: error: unresolved doc reference [showSystemContextMenu]
dartdoc:stderr: from services.SystemContextMenuController.hide: (file:///b/s/w/ir/x/w/flutter/packages/flutter/lib/src/services/text_input.dart:2554:16)
dartdoc:stderr: error: unresolved doc reference [hideSystemContextMenu]
dartdoc:stderr: from services.SystemContextMenuController.show: (file:///b/s/w/ir/x/w/flutter/packages/flutter/lib/src/services/text_input.dart:2509:16)
```
It's now possible to use the native-rendered text selection context menu on iOS. This sacrifices customizability in exchange for avoiding showing a notification when the user presses "Paste". It's off by default, but to enable, see the example system_context_menu.0.dart.
Reverts: flutter/flutter#143002
Initiated by: cbracken
Reason for reverting: unresolved docs links. See failure here: https://ci.chromium.org/ui/p/flutter/builders/prod/Linux%20docs_test/16540/overview
```
dartdoc:stdout: Generating docs for package flutter...
dartdoc:stderr: error: unresolved doc reference [TextInput.showSystemContextMenu]
dartdoc:stderr: from widgets.MediaQueryData.supportsShowingSystemContextMenu: (file:///b/s/w/ir/x/w/flutter/packages/flutt
Original PR Author: justinmc
Reviewed By: {Renzo-Olivares, hellohuanlin}
This change reverts the following previous change:
In order to work around the fact that iOS 15 shows a notification on pressing Flutter's paste button (https://github.com/flutter/flutter/issues/103163), this PR allows showing the iOS system context menu in text fields.
<img width="385" alt="Screenshot 2024-02-06 at 11 52 25 AM" src="https://github.com/flutter/flutter/assets/389558/d82e18ee-b8a3-4082-9225-cf47fa7f3674">
It is currently opt-in, which a user would typically do like this (also in example system_context_menu.0.dart):
```dart
contextMenuBuilder: (BuildContext context, EditableTextState editableTextState) {
// If supported, show the system context menu.
if (SystemContextMenu.isSupported(context)) {
return SystemContextMenu.editableText(
editableTextState: editableTextState,
);
}
// Otherwise, show the flutter-rendered context menu for the current
// platform.
return AdaptiveTextSelectionToolbar.editableText(
editableTextState: editableTextState,
);
},
```
Requires engine PR https://github.com/flutter/engine/pull/50095.
## API changes
### SystemContextMenu
A widget that shows the system context menu when built, and removes it when disposed. The main high-level way that most users would use this PR. Only works on later versions of iOS.
### SystemContextMenuController
Used under the hood to hide and show a system context menu. There can only be one visible at a time.
### MediaQuery.supportsShowingSystemContextMenu
Sent by the iOS embedder to tell the framework whether or not the platform supports showing the system context menu. That way the framework, or Flutter developers, can decide to show a different menu.
### `flutter/platform ContextMenu.showSystemContextMenu`
Sent by the framework to show the menu at a given `targetRect`, which is the current selection rect.
### `flutter/platform ContextMenu.hideSystemContextMenu`
Sent by the framework to hide the menu. Typically not needed, because the platform will hide the menu when the user taps outside of it and after the user presses a button, but it handles edge cases where the user programmatically rebuilds the context menu, for example.
### `flutter/platform System.onDismissSystemContextMenu`
Sent by the iOS embedder to indicate that the system context menu has been hidden by the system, such as when the user taps outside of the menu. This is useful when there are multiple instances of SystemContextMenu, such as with multiple text fields.
It's now possible to use the native-rendered text selection context menu on iOS. This sacrifices customizability in exchange for avoiding showing a notification when the user presses "Paste". It's off by default, but to enable, see the example system_context_menu.0.dart.
This PR contributes to https://github.com/flutter/flutter/issues/130459
### Description
- Updates `examples/api/lib/widgets/animated_size/animated_size.0.dart` API example by using `SizedBox` to size the surrounding of the `FlutterLogo` while setting the constant `FlutterLogo` size. This was done because `FlutterLogo` already has size animation under the hood, and the main goal of this example is to show `AnimatedSize` usage
- Adds test for `examples/api/lib/widgets/animated_size/animated_size.0.dart`
This PR contributes to https://github.com/flutter/flutter/issues/130459
### Description
- Updates `examples/api/lib/widgets/async/stream_builder.0.dart`
- Adds test for `examples/api/lib/widgets/async/stream_builder.0.dart`
DDS was temporarily pinned to 4.1.0 because 4.2.0 triggered some test
failures (see https://github.com/flutter/flutter/pull/147250). Those
failures should be fixed by vm_service 14.2.2, so this unpins DDS and
rolls both of these packages (along with devtools_shared, which is a DDS
dependency).
(If the bot updates vm_service before this is done, I can rebase over
that will reduce the size of this PR to just a few files)
This PR contributes to https://github.com/flutter/flutter/issues/130459
### Description
- Corrects the name for `examples/api/test/widgets/shortcuts/callback_shortcuts.0_test.dart` test file
- Update tests for `examples/api/lib/widgets/shortcuts/callback_shortcuts.0.dart`
This PR contributes to https://github.com/flutter/flutter/issues/130459
### Description
- Adds tests for `examples/api/lib/widgets/shortcuts/shortcuts.0.dart`
- Adds tests for `examples/api/lib/widgets/shortcuts/shortcuts.1.dart`
## Description
This introduces a list of packages that we will explicitly not pin. It is to be used for things where the package isn't actually published, but is a transitive dependency of another package included in the SDK. This happens with the `macros` package, for instance, which depends on the private, unpublished, `_macros` package where the SDK does some tricky things to depend on it (it depends on "any", but ships it as part of the SDK).
Also ran `flutter update-packages --force-update` to update all of the pubspec files.
## Related Issues
- Fixes#147656
## Tests
- Added a test that makes sure that explicitly unpinned packages don't show up in the pinned list.
This PR contributes to https://github.com/flutter/flutter/issues/130459
### Description
- Fixes name of the `examples/api/lib/widgets/shortcuts/single_activator.single_activator.0.dart`
- Adds tests for `examples/api/lib/widgets/shortcuts/single_activator.0.dart`
- added language for all code blocks
- replaced `bash` or `shell` with `sh` for consistency.
- added `sh` and `console` in the GitHub template link generator.
- updated test for GitHub template.
This PR contributes to https://github.com/flutter/flutter/issues/130459
### Description
- Adds `examples/api/lib/widgets/shortcuts/character_activator.0.dart` test
- Fixes the description of the `examples/api/lib/widgets/shortcuts/character_activator.0.dart` example
## Description
This fixes an issue in the creation of the `FocusScope` in a route: the route should be creating the `FocusScope` widget it has with `withExternalFocusNode`, since it is modifying the node attributes in a builder.
Also modified some `AnimatedBuilder`s to be `ListenableBuilder`s, since they're not using animations (no functionality change there, since the implementation of the two is identical).
## Related Issues
- #147256
- Fixes#146844
## Tests
- Updated example test.
In the `examples/api`, the Android platform missed this step while migrating to the declarative plugins {} block described in [flutter-gradle-plugin-apply](https://docs.flutter.dev/release/breaking-changes/flutter-gradle-plugin-apply), so all examples of `examples/api` cannot run.
Fixes#147100
*If you had to change anything in the [flutter/tests] repo, include a link to the migration guide as per the [breaking change policy].*
Here's another PR with a couple of typos fixed. As you can see there was a typo in _fileReferenceI**n**dentifiers_, in class _ParsedProjectInfo._ Maybe we should do some check on that since I'm not sure if that property is used somewhere outside Flutter?
This PR contributes to https://github.com/flutter/flutter/issues/130459
### Description
- Adds `examples/api/test/widgets/gesture_detector/gesture_detector.0_test.dart` test
- Adds `examples/api/test/widgets/gesture_detector/gesture_detector.1_test.dart` test
Reverts: flutter/flutter#139164
Initiated by: chunhtai
Reason for reverting: hard breaking change
Original PR Author: chunhtai
Reviewed By: {justinmc}
This change reverts the following previous change:
Adds a generic type and pop result to popscope and its friend.
The use cases are to be able to capture the result when the pop is called.
migration guide: https://github.com/flutter/website/pull/9872
Adds a generic type and pop result to popscope and its friend.
The use cases are to be able to capture the result when the pop is called.
migration guide: https://github.com/flutter/website/pull/9872
The interface for `ArgResults` from `package:args` has added new fields. Change the implementations of these in the conductor to extend `Fake` so that these aren't analyzer errors.
This broke the pub roll here: https://github.com/flutter/flutter/pull/146642#issuecomment-2050169629
This adds support for adding the `--wasm` flag to `flutter run` and `flutter drive`
* Emits errors if you attempt to use the skwasm renderer without the `--wasm` flag
* Emits errors if you try to use `--wasm` when not using a web device
* Uses the skwasm renderer by default if you pass `--wasm` and no `--web-renderer`