Saltar al contenido principal

Cambio en el orden de cierre de RawMenuAnchor

Al cerrar un `RawMenuAnchor`, ahora se activan los callbacks `onClose` y `onCloseRequested` para todos los `RawMenuAnchor` descendientes en una secuencia coordinada.

Resumen

#

Al cerrar un RawMenuAnchor, ahora se activan los callbacks onCloseRequested y onClose para todos los RawMenuAnchor descendientes. El callback onCloseRequested se activa de arriba hacia abajo (top-down), comenzando desde el RawMenuAnchor que lo originó y pasando a sus descendientes, mientras que el callback onClose se activa de abajo hacia arriba (bottom-up). Si un RawMenuAnchor ya está cerrado, las llamadas a MenuController.close y MenuController.closeChildren no activan el callback onCloseRequested.

Contexto

#

RawMenuAnchor es un Widget de bajo nivel que se utiliza para construir sistemas de menús personalizados. Anteriormente, un RawMenuAnchor no notificaba automáticamente a sus descendientes cuando se cerraba. Tenías que llamar manualmente a controller.closeChildren() dentro del callback onCloseRequested para cerrar los RawMenuAnchor descendientes.

Además, el tiempo de ejecución del callback onClose era inconsistente. El onClose de un RawMenuAnchor padre podía ejecutarse antes de que sus descendientes hubieran terminado de cerrarse.

El comportamiento actualizado garantiza que cuando un RawMenuAnchor padre comienza a cerrarse, posteriormente activa onCloseRequested para todos sus RawMenuAnchor descendientes de manera descendente (top-down).

Cuando se llama a hideOverlay desde dentro de onCloseRequested para cerrar el menú, todos los RawMenuAnchor descendientes tienen sus callbacks onClose ejecutados en un orden ascendente (bottom-up). Esto significa que el RawMenuAnchor abierto más recientemente ahora tiene su callback onClose ejecutado primero, seguido por su padre, y así sucesivamente en la jerarquía.

Este diseño permite una secuencia de cierre coordinada donde los RawMenuAnchor hijos pueden realizar cualquier limpieza necesaria antes de que sus padres finalicen el proceso de cierre.

Finalmente, si un RawMenuAnchor ya está cerrado, las llamadas a MenuController.close y MenuController.closeChildren no activan el callback onCloseRequested, evitando ejecuciones innecesarias de callbacks.

Guía de migración

#

Si tu código no sobrescribe la implementación predeterminada de RawMenuAnchor.onCloseRequested o tu RawMenuAnchor no contiene submenús, no se requieren cambios.

Si tienes una implementación personalizada de onCloseRequested en un RawMenuAnchor que contiene submenús, ahora se llama a controller.closeChildren() automáticamente cuando se cierra el menú padre. Asegúrate de que tu implementación de onCloseRequested siga comportándose correctamente con esta llamada automática. Las llamadas inmediatas a controller.closeChildren() dentro de tu callback onCloseRequested ya no son necesarias. Elimina esas llamadas.

Además, si tu lógica dependía de que el callback onClose del padre se disparara antes que el de sus descendientes, refactoriza tu código para tener en cuenta el nuevo orden de ejecución ascendente (bottom-up).

Código antes de la migración:

dart
RawMenuAnchor(
  controller: menuController,
  onCloseRequested: (hideOverlay) {
    if (!animationController.isForwardOrCompleted) {
      return;
    }

    // Descendant submenus must be closed before the parent menu.
    // This is now handled automatically, so this call is no longer necessary.
    menuController.closeChildren();
    animationController.reverse().whenComplete(hideOverlay);
  },
  onClose: () {
    // This might have executed before descendants called onClose().
    _handleMenuClosed();
  },
  // ...
)

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

dart
RawMenuAnchor(
  controller: menuController,
  onCloseRequested: (hideOverlay) {
    if (!animationController.isForwardOrCompleted) {
      return;
    }

    // `menuController.closeChildren()` is now called automatically.
    animationController.reverse().whenComplete(hideOverlay);
  },
  onClose: () {
    // This now executes only after all descendant submenus have
    // called `onClose()`.
    _handleMenuClosed();
  },
  // ...
)

Timeline

#

Introducido en la versión: 3.44.0-0.1.pre
En el lanzamiento estable: 3.44

Referencias

#

Documentación de la API:

Issues relevantes:

PRs relevantes: