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#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.