Saltar al contenido principal

Barras de desplazamiento predeterminadas en Desktop

ScrollBehaviors ahora construirá automáticamente Scrollbars en plataformas de escritorio.

Resumen

#

Los ScrollBehavior ahora aplican automáticamente Scrollbars a los widgets de desplazamiento en plataformas de escritorio: Mac, Windows y Linux.

Contexto

#

Antes de este cambio, las Scrollbars se aplicaban a los widgets de desplazamiento manualmente por el desarrollador en todas las plataformas. Esto no coincidía con las expectativas del desarrollador al ejecutar aplicaciones de Flutter en plataformas de escritorio.

Ahora, el ScrollBehavior heredado aplica una Scrollbar automáticamente a la mayoría de los widgets de desplazamiento. Esto es similar a cómo GlowingOverscrollIndicator es creado por ScrollBehavior. Los pocos widgets que están exentos de este comportamiento se enumeran a continuación.

Para proporcionar una mejor gestión y control de esta función, también se ha actualizado ScrollBehavior. El método buildViewportChrome, que aplicaba un GlowingOverscrollIndicator, ha sido deprecado. En su lugar, ScrollBehavior ahora admite métodos individuales para decorar el viewport: buildScrollbar y buildOverscrollIndicator. Estos métodos pueden ser anulados para controlar lo que se construye alrededor del scrollable.

Además, las subclases de ScrollBehavior, MaterialScrollBehavior y CupertinoScrollBehavior, se han hecho públicas, lo que permite a los desarrolladores extender y construir sobre los otros ScrollBehaviors existentes en el framework. Estas subclasses eran anteriormente privadas.

Descripción del cambio

#

El enfoque anterior requería que los desarrolladores crearan sus propias Scrollbars en todas las plataformas. En algunos casos de uso, sería necesario proporcionar un ScrollController al Scrollbar y al widget desplazable.

dart
final ScrollController controller = ScrollController();
Scrollbar(
  controller: controller,
  child: ListView.builder(
    controller: controller,
    itemBuilder: (BuildContext context, int index) {
      return Text('Item $index');
    }
  )
);

El ScrollBehavior ahora aplica la Scrollbar automáticamente cuando se ejecuta en escritorio, y se encarga de proporcionar el ScrollController a la Scrollbar por ti.

dart
final ScrollController controller = ScrollController();
ListView.builder(
  controller: controller,
  itemBuilder: (BuildContext context, int index) {
   return Text('Item $index');
 }
);

Algunos widgets en el framework están exentos de esta aplicación automática de Scrollbar. Ellos son:

  • EditableText, cuando maxLines es 1.
  • ListWheelScrollView
  • PageView
  • NestedScrollView

Dado que estos widgets anulan manualmente el ScrollBehavior heredado para eliminar las Scrollbars, todos estos widgets ahora tienen un parámetro scrollBehavior para que se pueda proporcionar uno para usar en lugar de la anulación.

Este cambio no causó fallos en las pruebas, cierres inesperados ni mensajes de error durante el desarrollo, pero puede provocar que se rendericen dos Scrollbars en tu aplicación si estás agregando manualmente Scrollbars en plataformas de escritorio.

Si ves esto en tu aplicación, existen varias formas de controlar y configurar esta característica.

  • Elimina las Scrollbars aplicadas manualmente en tu aplicación al ejecutarla en escritorio.

  • Extiende ScrollBehavior, MaterialScrollBehavior, o CupertinoScrollBehavior para modificar el comportamiento predeterminado.

    • Con tu propio ScrollBehavior, puedes aplicarlo a nivel de toda la aplicación configurando MaterialApp.scrollBehavior o CupertinoApp.scrollBehavior.
    • O, si deseas aplicarlo solo a widgets específicos, agrega una ScrollConfiguration encima del widget en cuestión con tu ScrollBehavior personalizado.

Tus widgets desplazables luego heredan esto y reflejan este comportamiento.

  • Instead of creating your own ScrollBehavior, another option for changing the default behavior is to copy the existing ScrollBehavior, and toggle the desired feature.
    • Crea una ScrollConfiguration en tu árbol de widgets y proporciona una copia modificada del ScrollBehavior existente en el contexto actual usando copyWith.

Guía de migración

#

Eliminación manual de Scrollbars en escritorio

#

Código antes de la migración:

dart
final ScrollController controller = ScrollController();
Scrollbar(
  controller: controller,
  child: ListView.builder(
    controller: controller,
    itemBuilder: (BuildContext context, int index) {
      return Text('Item $index');
    }
  )
);

Código después de la migración:

dart
final ScrollController controller = ScrollController();
final Widget child = ListView.builder(
  controller: controller,
  itemBuilder: (BuildContext context, int index) {
    return Text('Item $index');
  }
);
// Only manually add a `Scrollbar` when not on desktop platforms.
// Or, see other migrations for changing `ScrollBehavior`.
switch (currentPlatform) {
  case TargetPlatform.linux:
  case TargetPlatform.macOS:
  case TargetPlatform.windows:
    return child;
  case TargetPlatform.android:
  case TargetPlatform.fuchsia:
  case TargetPlatform.iOS:
    return Scrollbar(
      controller: controller,
      child: child;
    );
}

Establecer un ScrollBehavior personalizado para tu aplicación

#

Código antes de la migración:

dart
// MaterialApps previously had a private ScrollBehavior.
MaterialApp(
  // ...
);

Código después de la migración:

dart
// MaterialApps previously had a private ScrollBehavior.
// This is available to extend now.
class MyCustomScrollBehavior extends MaterialScrollBehavior {
  // Override behavior methods like buildOverscrollIndicator and buildScrollbar
}

// ScrollBehavior can now be configured for an entire application.
MaterialApp(
  scrollBehavior: MyCustomScrollBehavior(),
  // ...
);

Establecer un ScrollBehavior personalizado para un widget específico

#

Código antes de la migración:

dart
final ScrollController controller = ScrollController();
ListView.builder(
  controller: controller,
  itemBuilder: (BuildContext context, int index) {
   return Text('Item $index');
 }
);

Código después de la migración:

dart
// MaterialApps previously had a private ScrollBehavior.
// This is available to extend now.
class MyCustomScrollBehavior extends MaterialScrollBehavior {
  // Override behavior methods like buildOverscrollIndicator and buildScrollbar
}

// ScrollBehavior can be set for a specific widget.
final ScrollController controller = ScrollController();
ScrollConfiguration(
  behavior: MyCustomScrollBehavior(),
  child: ListView.builder(
    controller: controller,
    itemBuilder: (BuildContext context, int index) {
     return Text('Item $index');
    }
  ),
);

Copiar y modificar un ScrollBehavior existente

#

Código antes de la migración:

dart
final ScrollController controller = ScrollController();
ListView.builder(
  controller: controller,
  itemBuilder: (BuildContext context, int index) {
   return Text('Item $index');
 }
);

Código después de la migración:

dart
// ScrollBehavior can be copied and adjusted.
final ScrollController controller = ScrollController();
ScrollConfiguration(
  behavior: ScrollConfiguration.of(context).copyWith(scrollbars: false),
  child: ListView.builder(
    controller: controller,
    itemBuilder: (BuildContext context, int index) {
     return Text('Item $index');
    }
  ),
);

Timeline

#

Introducido en la versión: 2.2.0-10.0.pre
En la versión estable: 2.2.0

Referencias

#

Documentación de la API:

Issues relevantes:

PRs relevantes: