mirror of
https://github.com/flutter/flutter.git
synced 2025-06-03 00:51:18 +00:00
Add display features to MediaQuery (#92906)
This commit is contained in:
parent
1c4128c703
commit
a35e7aaed9
@ -105,7 +105,8 @@ class MediaQueryData {
|
||||
this.disableAnimations = false,
|
||||
this.boldText = false,
|
||||
this.navigationMode = NavigationMode.traditional,
|
||||
this.gestureSettings = const DeviceGestureSettings(touchSlop: kTouchSlop)
|
||||
this.gestureSettings = const DeviceGestureSettings(touchSlop: kTouchSlop),
|
||||
this.displayFeatures = const <ui.DisplayFeature>[],
|
||||
}) : assert(size != null),
|
||||
assert(devicePixelRatio != null),
|
||||
assert(textScaleFactor != null),
|
||||
@ -121,7 +122,8 @@ class MediaQueryData {
|
||||
assert(disableAnimations != null),
|
||||
assert(boldText != null),
|
||||
assert(navigationMode != null),
|
||||
assert(gestureSettings != null);
|
||||
assert(gestureSettings != null),
|
||||
assert(displayFeatures != null);
|
||||
|
||||
/// Creates data for a media query based on the given window.
|
||||
///
|
||||
@ -146,7 +148,8 @@ class MediaQueryData {
|
||||
highContrast = window.accessibilityFeatures.highContrast,
|
||||
alwaysUse24HourFormat = window.alwaysUse24HourFormat,
|
||||
navigationMode = NavigationMode.traditional,
|
||||
gestureSettings = DeviceGestureSettings.fromWindow(window);
|
||||
gestureSettings = DeviceGestureSettings.fromWindow(window),
|
||||
displayFeatures = window.displayFeatures;
|
||||
|
||||
/// The size of the media in logical pixels (e.g, the size of the screen).
|
||||
///
|
||||
@ -351,6 +354,17 @@ class MediaQueryData {
|
||||
/// gesture behavior over the framework constants.
|
||||
final DeviceGestureSettings gestureSettings;
|
||||
|
||||
/// {@macro dart.ui.ViewConfiguration.displayFeatures}
|
||||
///
|
||||
/// See also:
|
||||
///
|
||||
/// * [dart:ui.DisplayFeatureType], which lists the different types of
|
||||
/// display features and explains the differences between them.
|
||||
/// * [dart:ui.DisplayFeatureState], which lists the possible states for
|
||||
/// folding features ([dart:ui.DisplayFeatureType.fold] and
|
||||
/// [dart:ui.DisplayFeatureType.hinge]).
|
||||
final List<ui.DisplayFeature> displayFeatures;
|
||||
|
||||
/// The orientation of the media (e.g., whether the device is in landscape or
|
||||
/// portrait mode).
|
||||
Orientation get orientation {
|
||||
@ -376,6 +390,7 @@ class MediaQueryData {
|
||||
bool? boldText,
|
||||
NavigationMode? navigationMode,
|
||||
DeviceGestureSettings? gestureSettings,
|
||||
List<ui.DisplayFeature>? displayFeatures,
|
||||
}) {
|
||||
return MediaQueryData(
|
||||
size: size ?? this.size,
|
||||
@ -394,6 +409,7 @@ class MediaQueryData {
|
||||
boldText: boldText ?? this.boldText,
|
||||
navigationMode: navigationMode ?? this.navigationMode,
|
||||
gestureSettings: gestureSettings ?? this.gestureSettings,
|
||||
displayFeatures: displayFeatures ?? this.displayFeatures,
|
||||
);
|
||||
}
|
||||
|
||||
@ -445,6 +461,7 @@ class MediaQueryData {
|
||||
accessibleNavigation: accessibleNavigation,
|
||||
boldText: boldText,
|
||||
gestureSettings: gestureSettings,
|
||||
displayFeatures: displayFeatures,
|
||||
);
|
||||
}
|
||||
|
||||
@ -494,6 +511,7 @@ class MediaQueryData {
|
||||
accessibleNavigation: accessibleNavigation,
|
||||
boldText: boldText,
|
||||
gestureSettings: gestureSettings,
|
||||
displayFeatures: displayFeatures,
|
||||
);
|
||||
}
|
||||
|
||||
@ -543,6 +561,7 @@ class MediaQueryData {
|
||||
accessibleNavigation: accessibleNavigation,
|
||||
boldText: boldText,
|
||||
gestureSettings: gestureSettings,
|
||||
displayFeatures: displayFeatures,
|
||||
);
|
||||
}
|
||||
|
||||
@ -565,7 +584,8 @@ class MediaQueryData {
|
||||
&& other.accessibleNavigation == accessibleNavigation
|
||||
&& other.boldText == boldText
|
||||
&& other.navigationMode == navigationMode
|
||||
&& other.gestureSettings == gestureSettings;
|
||||
&& other.gestureSettings == gestureSettings
|
||||
&& listEquals(other.displayFeatures, displayFeatures);
|
||||
}
|
||||
|
||||
@override
|
||||
@ -586,6 +606,7 @@ class MediaQueryData {
|
||||
boldText,
|
||||
navigationMode,
|
||||
gestureSettings,
|
||||
hashList(displayFeatures),
|
||||
);
|
||||
}
|
||||
|
||||
@ -607,6 +628,7 @@ class MediaQueryData {
|
||||
'boldText: $boldText',
|
||||
'navigationMode: ${navigationMode.name}',
|
||||
'gestureSettings: $gestureSettings',
|
||||
'displayFeatures: $displayFeatures',
|
||||
];
|
||||
return '${objectRuntimeType(this, 'MediaQueryData')}(${properties.join(', ')})';
|
||||
}
|
||||
|
@ -2,7 +2,7 @@
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
import 'dart:ui' show Brightness;
|
||||
import 'dart:ui' show Brightness, DisplayFeature, DisplayFeatureState, DisplayFeatureType;
|
||||
|
||||
import 'package:flutter/gestures.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
@ -112,6 +112,7 @@ void main() {
|
||||
expect(data.highContrast, false);
|
||||
expect(data.platformBrightness, Brightness.light);
|
||||
expect(data.gestureSettings.touchSlop, null);
|
||||
expect(data.displayFeatures, isEmpty);
|
||||
});
|
||||
|
||||
testWidgets('MediaQueryData.copyWith defaults to source', (WidgetTester tester) async {
|
||||
@ -132,6 +133,7 @@ void main() {
|
||||
expect(copied.highContrast, data.highContrast);
|
||||
expect(copied.platformBrightness, data.platformBrightness);
|
||||
expect(copied.gestureSettings, data.gestureSettings);
|
||||
expect(copied.displayFeatures, data.displayFeatures);
|
||||
});
|
||||
|
||||
testWidgets('MediaQuery.copyWith copies specified values', (WidgetTester tester) async {
|
||||
@ -145,6 +147,13 @@ void main() {
|
||||
const EdgeInsets customViewInsets = EdgeInsets.all(1.67262);
|
||||
const EdgeInsets customSystemGestureInsets = EdgeInsets.all(1.5556);
|
||||
const DeviceGestureSettings gestureSettings = DeviceGestureSettings(touchSlop: 8.0);
|
||||
const List<DisplayFeature> customDisplayFeatures = <DisplayFeature>[
|
||||
DisplayFeature(
|
||||
bounds: Rect.zero,
|
||||
type: DisplayFeatureType.cutout,
|
||||
state: DisplayFeatureState.unknown,
|
||||
),
|
||||
];
|
||||
|
||||
final MediaQueryData data = MediaQueryData.fromWindow(WidgetsBinding.instance!.window);
|
||||
final MediaQueryData copied = data.copyWith(
|
||||
@ -163,6 +172,7 @@ void main() {
|
||||
highContrast: true,
|
||||
platformBrightness: Brightness.dark,
|
||||
gestureSettings: gestureSettings,
|
||||
displayFeatures: customDisplayFeatures,
|
||||
);
|
||||
expect(copied.size, customSize);
|
||||
expect(copied.devicePixelRatio, customDevicePixelRatio);
|
||||
@ -179,6 +189,7 @@ void main() {
|
||||
expect(copied.highContrast, true);
|
||||
expect(copied.platformBrightness, Brightness.dark);
|
||||
expect(copied.gestureSettings, gestureSettings);
|
||||
expect(copied.displayFeatures, customDisplayFeatures);
|
||||
});
|
||||
|
||||
testWidgets('MediaQuery.removePadding removes specified padding', (WidgetTester tester) async {
|
||||
@ -188,6 +199,13 @@ void main() {
|
||||
const EdgeInsets padding = EdgeInsets.only(top: 1.0, right: 2.0, left: 3.0, bottom: 4.0);
|
||||
const EdgeInsets viewPadding = EdgeInsets.only(top: 6.0, right: 8.0, left: 10.0, bottom: 12.0);
|
||||
const EdgeInsets viewInsets = EdgeInsets.only(top: 5.0, right: 6.0, left: 7.0, bottom: 8.0);
|
||||
const List<DisplayFeature> displayFeatures = <DisplayFeature>[
|
||||
DisplayFeature(
|
||||
bounds: Rect.zero,
|
||||
type: DisplayFeatureType.cutout,
|
||||
state: DisplayFeatureState.unknown,
|
||||
),
|
||||
];
|
||||
|
||||
late MediaQueryData unpadded;
|
||||
await tester.pumpWidget(
|
||||
@ -205,6 +223,7 @@ void main() {
|
||||
disableAnimations: true,
|
||||
boldText: true,
|
||||
highContrast: true,
|
||||
displayFeatures: displayFeatures,
|
||||
),
|
||||
child: Builder(
|
||||
builder: (BuildContext context) {
|
||||
@ -238,6 +257,7 @@ void main() {
|
||||
expect(unpadded.disableAnimations, true);
|
||||
expect(unpadded.boldText, true);
|
||||
expect(unpadded.highContrast, true);
|
||||
expect(unpadded.displayFeatures, displayFeatures);
|
||||
});
|
||||
|
||||
testWidgets('MediaQuery.removePadding only removes specified padding', (WidgetTester tester) async {
|
||||
@ -247,6 +267,13 @@ void main() {
|
||||
const EdgeInsets padding = EdgeInsets.only(top: 1.0, right: 2.0, left: 3.0, bottom: 4.0);
|
||||
const EdgeInsets viewPadding = EdgeInsets.only(top: 6.0, right: 8.0, left: 10.0, bottom: 12.0);
|
||||
const EdgeInsets viewInsets = EdgeInsets.only(top: 5.0, right: 6.0, left: 7.0, bottom: 8.0);
|
||||
const List<DisplayFeature> displayFeatures = <DisplayFeature>[
|
||||
DisplayFeature(
|
||||
bounds: Rect.zero,
|
||||
type: DisplayFeatureType.cutout,
|
||||
state: DisplayFeatureState.unknown,
|
||||
),
|
||||
];
|
||||
|
||||
late MediaQueryData unpadded;
|
||||
await tester.pumpWidget(
|
||||
@ -264,6 +291,7 @@ void main() {
|
||||
disableAnimations: true,
|
||||
boldText: true,
|
||||
highContrast: true,
|
||||
displayFeatures: displayFeatures,
|
||||
),
|
||||
child: Builder(
|
||||
builder: (BuildContext context) {
|
||||
@ -294,6 +322,7 @@ void main() {
|
||||
expect(unpadded.disableAnimations, true);
|
||||
expect(unpadded.boldText, true);
|
||||
expect(unpadded.highContrast, true);
|
||||
expect(unpadded.displayFeatures, displayFeatures);
|
||||
});
|
||||
|
||||
testWidgets('MediaQuery.removeViewInsets removes specified viewInsets', (WidgetTester tester) async {
|
||||
@ -303,6 +332,13 @@ void main() {
|
||||
const EdgeInsets padding = EdgeInsets.only(top: 5.0, right: 6.0, left: 7.0, bottom: 8.0);
|
||||
const EdgeInsets viewPadding = EdgeInsets.only(top: 6.0, right: 8.0, left: 10.0, bottom: 12.0);
|
||||
const EdgeInsets viewInsets = EdgeInsets.only(top: 1.0, right: 2.0, left: 3.0, bottom: 4.0);
|
||||
const List<DisplayFeature> displayFeatures = <DisplayFeature>[
|
||||
DisplayFeature(
|
||||
bounds: Rect.zero,
|
||||
type: DisplayFeatureType.cutout,
|
||||
state: DisplayFeatureState.unknown,
|
||||
),
|
||||
];
|
||||
|
||||
late MediaQueryData unpadded;
|
||||
await tester.pumpWidget(
|
||||
@ -320,6 +356,7 @@ void main() {
|
||||
disableAnimations: true,
|
||||
boldText: true,
|
||||
highContrast: true,
|
||||
displayFeatures: displayFeatures,
|
||||
),
|
||||
child: Builder(
|
||||
builder: (BuildContext context) {
|
||||
@ -353,6 +390,7 @@ void main() {
|
||||
expect(unpadded.disableAnimations, true);
|
||||
expect(unpadded.boldText, true);
|
||||
expect(unpadded.highContrast, true);
|
||||
expect(unpadded.displayFeatures, displayFeatures);
|
||||
});
|
||||
|
||||
testWidgets('MediaQuery.removeViewInsets removes only specified viewInsets', (WidgetTester tester) async {
|
||||
@ -362,6 +400,13 @@ void main() {
|
||||
const EdgeInsets padding = EdgeInsets.only(top: 5.0, right: 6.0, left: 7.0, bottom: 8.0);
|
||||
const EdgeInsets viewPadding = EdgeInsets.only(top: 6.0, right: 8.0, left: 10.0, bottom: 12.0);
|
||||
const EdgeInsets viewInsets = EdgeInsets.only(top: 1.0, right: 2.0, left: 3.0, bottom: 4.0);
|
||||
const List<DisplayFeature> displayFeatures = <DisplayFeature>[
|
||||
DisplayFeature(
|
||||
bounds: Rect.zero,
|
||||
type: DisplayFeatureType.cutout,
|
||||
state: DisplayFeatureState.unknown,
|
||||
),
|
||||
];
|
||||
|
||||
late MediaQueryData unpadded;
|
||||
await tester.pumpWidget(
|
||||
@ -379,6 +424,7 @@ void main() {
|
||||
disableAnimations: true,
|
||||
boldText: true,
|
||||
highContrast: true,
|
||||
displayFeatures: displayFeatures,
|
||||
),
|
||||
child: Builder(
|
||||
builder: (BuildContext context) {
|
||||
@ -409,6 +455,7 @@ void main() {
|
||||
expect(unpadded.disableAnimations, true);
|
||||
expect(unpadded.boldText, true);
|
||||
expect(unpadded.highContrast, true);
|
||||
expect(unpadded.displayFeatures, displayFeatures);
|
||||
});
|
||||
|
||||
testWidgets('MediaQuery.removeViewPadding removes specified viewPadding', (WidgetTester tester) async {
|
||||
@ -418,6 +465,13 @@ void main() {
|
||||
const EdgeInsets padding = EdgeInsets.only(top: 5.0, right: 6.0, left: 7.0, bottom: 8.0);
|
||||
const EdgeInsets viewPadding = EdgeInsets.only(top: 6.0, right: 8.0, left: 10.0, bottom: 12.0);
|
||||
const EdgeInsets viewInsets = EdgeInsets.only(top: 1.0, right: 2.0, left: 3.0, bottom: 4.0);
|
||||
const List<DisplayFeature> displayFeatures = <DisplayFeature>[
|
||||
DisplayFeature(
|
||||
bounds: Rect.zero,
|
||||
type: DisplayFeatureType.cutout,
|
||||
state: DisplayFeatureState.unknown,
|
||||
),
|
||||
];
|
||||
|
||||
late MediaQueryData unpadded;
|
||||
await tester.pumpWidget(
|
||||
@ -435,6 +489,7 @@ void main() {
|
||||
disableAnimations: true,
|
||||
boldText: true,
|
||||
highContrast: true,
|
||||
displayFeatures: displayFeatures,
|
||||
),
|
||||
child: Builder(
|
||||
builder: (BuildContext context) {
|
||||
@ -468,6 +523,7 @@ void main() {
|
||||
expect(unpadded.disableAnimations, true);
|
||||
expect(unpadded.boldText, true);
|
||||
expect(unpadded.highContrast, true);
|
||||
expect(unpadded.displayFeatures, displayFeatures);
|
||||
});
|
||||
|
||||
testWidgets('MediaQuery.removeViewPadding removes only specified viewPadding', (WidgetTester tester) async {
|
||||
@ -477,6 +533,13 @@ void main() {
|
||||
const EdgeInsets padding = EdgeInsets.only(top: 5.0, right: 6.0, left: 7.0, bottom: 8.0);
|
||||
const EdgeInsets viewPadding = EdgeInsets.only(top: 6.0, right: 8.0, left: 10.0, bottom: 12.0);
|
||||
const EdgeInsets viewInsets = EdgeInsets.only(top: 1.0, right: 2.0, left: 3.0, bottom: 4.0);
|
||||
const List<DisplayFeature> displayFeatures = <DisplayFeature>[
|
||||
DisplayFeature(
|
||||
bounds: Rect.zero,
|
||||
type: DisplayFeatureType.cutout,
|
||||
state: DisplayFeatureState.unknown,
|
||||
),
|
||||
];
|
||||
|
||||
late MediaQueryData unpadded;
|
||||
await tester.pumpWidget(
|
||||
@ -494,6 +557,7 @@ void main() {
|
||||
disableAnimations: true,
|
||||
boldText: true,
|
||||
highContrast: true,
|
||||
displayFeatures: displayFeatures,
|
||||
),
|
||||
child: Builder(
|
||||
builder: (BuildContext context) {
|
||||
@ -524,6 +588,7 @@ void main() {
|
||||
expect(unpadded.disableAnimations, true);
|
||||
expect(unpadded.boldText, true);
|
||||
expect(unpadded.highContrast, true);
|
||||
expect(unpadded.displayFeatures, displayFeatures);
|
||||
});
|
||||
|
||||
testWidgets('MediaQuery.textScaleFactorOf', (WidgetTester tester) async {
|
||||
|
@ -134,6 +134,20 @@ class TestWindow implements ui.SingletonFlutterWindow {
|
||||
onMetricsChanged?.call();
|
||||
}
|
||||
|
||||
@override
|
||||
List<ui.DisplayFeature> get displayFeatures => _displayFeaturesTestValue ?? _window.displayFeatures;
|
||||
List<ui.DisplayFeature>? _displayFeaturesTestValue;
|
||||
/// Hides the real displayFeatures and reports the given [displayFeaturesTestValue] instead.
|
||||
set displayFeaturesTestValue(List<ui.DisplayFeature> displayFeaturesTestValue) { // ignore: avoid_setters_without_getters
|
||||
_displayFeaturesTestValue = displayFeaturesTestValue;
|
||||
onMetricsChanged?.call();
|
||||
}
|
||||
/// Deletes any existing test padding and returns to using the real padding.
|
||||
void clearDisplayFeaturesTestValue() {
|
||||
_displayFeaturesTestValue = null;
|
||||
onMetricsChanged?.call();
|
||||
}
|
||||
|
||||
@override
|
||||
ui.WindowPadding get systemGestureInsets => _systemGestureInsetsTestValue ?? _window.systemGestureInsets;
|
||||
ui.WindowPadding? _systemGestureInsetsTestValue;
|
||||
@ -427,6 +441,7 @@ class TestWindow implements ui.SingletonFlutterWindow {
|
||||
clearLocaleTestValue();
|
||||
clearLocalesTestValue();
|
||||
clearPaddingTestValue();
|
||||
clearDisplayFeaturesTestValue();
|
||||
clearPhysicalSizeTestValue();
|
||||
clearSemanticsEnabledTestValue();
|
||||
clearTextScaleFactorTestValue();
|
||||
|
Loading…
Reference in New Issue
Block a user