El singleton window está deprecado
En preparación para admitir múltiples vistas y múltiples ventanas, el singleton window ha sido deprecado.
Resumen
#En preparación para admitir múltiples vistas y múltiples ventanas, el singleton window
ha sido deprecado. El código que dependía anteriormente del singleton window
debe buscar la vista específica sobre la que desea operar a través de la API
View.of
o interactuar directamente con PlatformDispatcher.
Contexto
#Originalmente, Flutter asumía que una aplicación solo consistiría en una única
vista (la ventana o window) en la que se puede dibujar el contenido. En un mundo multivista, esta
asunción ya no tiene sentido y las API que codifican esta asunción
han sido deprecadas. En su lugar, las aplicaciones y bibliotecas que dependían de estas API
deben elegir una vista específica en la que desean operar y
migrar a las nuevas API compatibles con multivista, tal como se describe en esta guía de migración.
Descripción del cambio
#Las API que se han deprecado como parte de este cambio son:
- La propiedad global
windowexpuesta pordart:ui. -
The
windowproperty on theBaseBindingclass, which is usually accessed viaGestureBinding.instance.window,SchedulerBinding.instance.window,ServicesBinding.instance.window,PaintingBinding.instance.window,SemanticsBinding.instance.window,RendererBinding.instance.window,WidgetsBinding.instance.window, oWidgetTester.binding.window.
- La clase
SingletonFlutterViewdedart:ui. TestWindowdeflutter_test, sus constructores, y todas sus propiedades y métodos.
Existen las siguientes opciones para migrar el código de la aplicación y de la biblioteca que depende de estas API deprecadas:
Si hay un BuildContext disponible, considera buscar el FlutterView actual
a través de View.of. Esto devuelve el FlutterView en el que
se dibujarán los widgets construidos por el método build asociado con el contexto dado.
El FlutterView proporciona acceso a la misma funcionalidad
que estaba disponible anteriormente en la clase deprecada SingletonFlutterView
devuelta por las propiedades deprecadas de window mencionadas anteriormente. Sin embargo, algunas
de las funcionalidades específicas de la plataforma se han trasladado a PlatformDispatcher,
a la cual se puede acceder desde el FlutterView devuelto por View.of
a través de
FlutterView.platformDispatcher. El uso de View.of es la forma preferida de
migrar fuera de las propiedades deprecadas mencionadas anteriormente.
Si no hay un BuildContext disponible para buscar un FlutterView, se
puede consultar directamente PlatformDispatcher para acceder a la funcionalidad específica
de la plataforma. También mantiene una lista de todos los FlutterViews disponibles en
PlatformDispatcher.views para acceder a la funcionalidad específica de la vista. Si es posible,
se debe acceder a PlatformDispatcher a través de un binding (por ejemplo,
WidgetsBinding.instance.platformDispatcher) en lugar de utilizar la propiedad estática
PlatformDispatcher.instance. Esto garantiza que la funcionalidad
de PlatformDispatcher se pueda simular (mock) correctamente en las pruebas.
Pruebas
#Para las pruebas que accedían a la propiedad WidgetTester.binding.window para cambiar
las propiedades de la ventana para las pruebas, están disponibles las siguientes migraciones:
En las pruebas escritas con testWidgets, se han añadido dos nuevas propiedades que
juntas reemplazan la funcionalidad de TestWindow.
-
WidgetTester.viewwill provide aTestFlutterViewthat can be modified similarly toWidgetTester.binding.window, but with only view-specific properties such as the size of a view, its display pixel ratio, etc.WidgetTester.viewOfestá disponible para ciertos casos de uso multivista, pero no debería ser necesario para ninguna migración desdeWidgetTester.binding.window.
WidgetTester.platformDispatcherproporcionará acceso a unTestPlatformDispatcherque se puede utilizar para modificar propiedades específicas de la plataforma como la configuración regional (locale) de la plataforma, si ciertas características del sistema están disponibles, etc.
Guía de migración
#En lugar de acceder a la propiedad estática window, el código de la aplicación y de la biblioteca
que tiene acceso a un BuildContext debe usar View.of para buscar el
FlutterView con el que está asociado el contexto. Algunas propiedades se han movido a
PlatformDispatcher accesible desde la vista a través del getter platformDispatcher.
Código antes de la migración:
Widget build(BuildContext context) {
final double dpr = WidgetsBinding.instance.window.devicePixelRatio;
final Locale locale = WidgetsBinding.instance.window.locale;
return Text('The device pixel ratio is $dpr and the locale is $locale.');
}
Código después de la migración:
Widget build(BuildContext context) {
final double dpr = View.of(context).devicePixelRatio;
final Locale locale = View.of(context).platformDispatcher.locale;
return Text('The device pixel ratio is $dpr and the locale is $locale.');
}
Si no hay un BuildContext disponible, se puede consultar directamente el PlatformDispatcher expuesto por los
bindings.
Código antes de la migración:
double getTextScaleFactor() {
return WidgetsBinding.instance.window.textScaleFactor;
}
Código después de la migración:
double getTextScaleFactor() {
// View.of(context).platformDispatcher.textScaleFactor if a BuildContext is available, otherwise:
return WidgetsBinding.instance.platformDispatcher.textScaleFactor;
}
Pruebas
#En las pruebas escritas con testWidget, se deben usar en su lugar los nuevos accesores
view y platformDispatcher.
Configurar propiedades específicas de la vista
#TestFlutterView también se ha esforzado por hacer que la API de pruebas sea más clara y más
concisa al usar setters con el mismo nombre que su getter relacionado en lugar de
setters con el sufijo TestValue.
Código antes de la migración:
testWidget('test name', (WidgetTester tester) async {
tester.binding.window.devicePixelRatioTestValue = 2.0;
tester.binding.window.displayFeaturesTestValue = <DisplayFeatures>[];
tester.binding.window.gestureSettingsTestValue = const GestureSettings(physicalTouchSlop: 100);
tester.binding.window.paddingTestValue = FakeViewPadding.zero;
tester.binding.window.physicalGeometryTestValue = const Rect.fromLTRB(0,0, 500, 800);
tester.binding.window.physicalSizeTestValue = const Size(300, 400);
tester.binding.window.systemGestureInsetsTestValue = FakeViewPadding.zero;
tester.binding.window.viewInsetsTestValue = FakeViewPadding.zero;
tester.binding.window.viewPaddingTestValue = FakeViewPadding.zero;
});
Código después de la migración
testWidget('test name', (WidgetTester tester) async {
tester.view.devicePixelRatio = 2.0;
tester.view.displayFeatures = <DisplayFeatures>[];
tester.view.gestureSettings = const GestureSettings(physicalTouchSlop: 100);
tester.view.padding = FakeViewPadding.zero;
tester.view.physicalGeometry = const Rect.fromLTRB(0,0, 500, 800);
tester.view.physicalSize = const Size(300, 400);
tester.view.systemGestureInsets = FakeViewPadding.zero;
tester.view.viewInsets = FakeViewPadding.zero;
tester.view.viewPadding = FakeViewPadding.zero;
});
Restablecer propiedades específicas de la vista
#TestFlutterView conserva la capacidad de restablecer propiedades individuales o toda
la vista pero, para ser más claros y consistentes, el nombre de estos
métodos ha cambiado de clear<property>TestValue y clearAllTestValues
a
reset<property> y reset respectivamente.
Restablecer propiedades individuales
#Código antes de la migración:
testWidget('test name', (WidgetTester tester) async {
addTearDown(tester.binding.window.clearDevicePixelRatioTestValue);
addTearDown(tester.binding.window.clearDisplayFeaturesTestValue);
addTearDown(tester.binding.window.clearGestureSettingsTestValue);
addTearDown(tester.binding.window.clearPaddingTestValue);
addTearDown(tester.binding.window.clearPhysicalGeometryTestValue);
addTearDown(tester.binding.window.clearPhysicalSizeTestValue);
addTearDown(tester.binding.window.clearSystemGestureInsetsTestValue);
addTearDown(tester.binding.window.clearViewInsetsTestValue);
addTearDown(tester.binding.window.clearViewPaddingTestValue);
});
Código después de la migración
testWidget('test name', (WidgetTester tester) async {
addTearDown(tester.view.resetDevicePixelRatio);
addTearDown(tester.view.resetDisplayFeatures);
addTearDown(tester.view.resetGestureSettings);
addTearDown(tester.view.resetPadding);
addTearDown(tester.view.resetPhysicalGeometry);
addTearDown(tester.view.resetPhysicalSize);
addTearDown(tester.view.resetSystemGestureInsets);
addTearDown(tester.view.resetViewInsets);
addTearDown(tester.view.resetViewPadding);
});
Restablecer todas las propiedades a la vez
#Código antes de la migración:
testWidget('test name', (WidgetTester tester) async {
addTearDown(tester.binding.window.clearAllTestValues);
});
Código después de la migración
testWidget('test name', (WidgetTester tester) async {
addTearDown(tester.view.reset);
});
Configurar propiedades específicas de la plataforma
#TestPlatformDispatcher conserva la misma funcionalidad y esquema de nombres para
los setters de prueba que tenía TestWindow, por lo que la migración de propiedades específicas de la plataforma
consiste principalmente en llamar a los mismos setters en el nuevo
accesor WidgetTester.platformDispatcher.
Código antes de la migración:
testWidgets('test name', (WidgetTester tester) async {
tester.binding.window.accessibilityFeaturesTestValue = FakeAccessibilityFeatures.allOn;
tester.binding.window.alwaysUse24HourFormatTestValue = false;
tester.binding.window.brieflyShowPasswordTestValue = true;
tester.binding.window.defaultRouteNameTestValue = '/test';
tester.binding.window.initialLifecycleStateTestValue = 'painting';
tester.binding.window.localesTestValue = <Locale>[const Locale('en-us'), const Locale('ar-jo')];
tester.binding.window.localeTestValue = const Locale('ar-jo');
tester.binding.window.nativeSpellCheckServiceDefinedTestValue = false;
tester.binding.window.platformBrightnessTestValue = Brightness.dark;
tester.binding.window.semanticsEnabledTestValue = true;
tester.binding.window.textScaleFactorTestValue = 2.0;
});
Código después de la migración:
testWidgets('test name', (WidgetTester tester) async {
tester.platformDispatcher.accessibilityFeaturesTestValue = FakeAccessibilityFeatures.allOn;
tester.platformDispatcher.alwaysUse24HourFormatTestValue = false;
tester.platformDispatcher.brieflyShowPasswordTestValue = true;
tester.platformDispatcher.defaultRouteNameTestValue = '/test';
tester.platformDispatcher.initialLifecycleStateTestValue = 'painting';
tester.platformDispatcher.localesTestValue = <Locale>[const Locale('en-us'), const Locale('ar-jo')];
tester.platformDispatcher.localeTestValue = const Locale('ar-jo');
tester.platformDispatcher.nativeSpellCheckServiceDefinedTestValue = false;
tester.platformDispatcher.platformBrightnessTestValue = Brightness.dark;
tester.platformDispatcher.semanticsEnabledTestValue = true;
tester.platformDispatcher.textScaleFactorTestValue = 2.0;
});
Restablecer propiedades específicas de la plataforma
#De manera similar a la configuración de propiedades, el restablecimiento de propiedades específicas de la plataforma consiste
principalmente en cambiar del accesor binding.window al accesor
platformDispatcher.
Restablecer propiedades individuales
#Código antes de la migración:
testWidgets('test name', (WidgetTester tester) async {
addTeardown(tester.binding.window.clearAccessibilityFeaturesTestValue);
addTeardown(tester.binding.window.clearAlwaysUse24HourFormatTestValue);
addTeardown(tester.binding.window.clearBrieflyShowPasswordTestValue);
addTeardown(tester.binding.window.clearDefaultRouteNameTestValue);
addTeardown(tester.binding.window.clearInitialLifecycleStateTestValue);
addTeardown(tester.binding.window.clearLocalesTestValue);
addTeardown(tester.binding.window.clearLocaleTestValue);
addTeardown(tester.binding.window.clearNativeSpellCheckServiceDefinedTestValue);
addTeardown(tester.binding.window.clearPlatformBrightnessTestValue);
addTeardown(tester.binding.window.clearSemanticsEnabledTestValue);
addTeardown(tester.binding.window.clearTextScaleFactorTestValue);
});
Código después de la migración:
testWidgets('test name', (WidgetTester tester) async {
addTeardown(tester.platformDispatcher.clearAccessibilityFeaturesTestValue);
addTeardown(tester.platformDispatcher.clearAlwaysUse24HourFormatTestValue);
addTeardown(tester.platformDispatcher.clearBrieflyShowPasswordTestValue);
addTeardown(tester.platformDispatcher.clearDefaultRouteNameTestValue);
addTeardown(tester.platformDispatcher.clearInitialLifecycleStateTestValue);
addTeardown(tester.platformDispatcher.clearLocalesTestValue);
addTeardown(tester.platformDispatcher.clearLocaleTestValue);
addTeardown(tester.platformDispatcher.clearNativeSpellCheckServiceDefinedTestValue);
addTeardown(tester.platformDispatcher.clearPlatformBrightnessTestValue);
addTeardown(tester.platformDispatcher.clearSemanticsEnabledTestValue);
addTeardown(tester.platformDispatcher.clearTextScaleFactorTestValue);
});
Restablecer todas las propiedades a la vez
#Código antes de la migración:
testWidgets('test name', (WidgetTester tester) async {
addTeardown(tester.binding.window.clearAllTestValues);
});
Código después de la migración:
testWidgets('test name', (WidgetTester tester) async {
addTeardown(tester.platformDispatcher.clearAllTestValues);
});
Timeline
#Introducido en la versión: 3.9.0-13.0.pre.20
En la versión estable: 3.10.0
Referencias
#Documentación de la API:
View.of-
FlutterView -
PlatformDispatcher -
TestPlatformDispatcher -
TestFlutterView -
TestWidgetsFlutterBinding.window
Issues relevantes:
PRs relevantes:
A menos que se indique lo contrario, la documentación de este sitio refleja Flutter 3.44.0. Página actualizada por última vez el 2026-05-05. Ver código fuente oreportar un problema.