es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Flutter: Evitar que el Listener hijo active el Listener padre.

Quiero implementar un menú de clic derecho en Flutter y el código se ve así:

Listener(
  onPointerDown: (event) {
    if (event.buttons == 2) {
      double dy = event.position.dy.ceilToDouble();
      double dx = event.position.dx.ceilToDouble();
      showMenu(
        context: context,
        position: RelativeRect.fromLTRB(dx, dy, dx, 0),
        items: [
          PopupMenuItem(child: const Text("Parent Menu 1"), onTap: () {}),
        ],
      );
    }
  }
  child: ExpansionTile(
    initiallyExpanded: true,
    iconColor: Colors.white,
    leading: const Icon(Icons.book),
    title: const Text(
      "Note",
      style: TextStyle(fontSize: 16.0, color: Colors.white),
    ),
    children: <widget>[
      Listener(
        onPointerDown: (event) {
          if (event.buttons == 2) {
            double dy = event.position.dy.ceilToDouble();
            double dx = event.position.dx.ceilToDouble();
            showMenu(
              context: context,
              position: RelativeRect.fromLTRB(dx, dy, dx, 0),
              items: [
                PopupMenuItem(child: const Text("Child Menu 1"), onTap: () {}),
                PopupMenuItem(child: const Text("Child Menu 2"), onTap: () {}),
              ],
            );
          }
        }
        child: ListTile(
          title: Text(
            formatTitle(),
            style: TextStyle(color: Colors.white, fontSize: fontSize ?? 14.0),
          ),
          dense: true,
          onTap: () {},
        ),
      )
    ],
  ),
)

Pero aparentemente, el onPointerDown del padre también se activa cuando se activa el onPointerDown del hijo.

Esto es lo que quería:

enter image description here

Pero esto es lo que obtuve:

enter image description here

Estoy ejecutando esto en Flutter en un escritorio de Linux.

Tags:  , ,

Answer

  1. Avatar for davy.ai

    Para evitar que se active onPointerDown del padre cuando se active onPointerDown del hijo, podemos agregar behavior: HitTestBehavior.translucent al widget Listener del hijo. El valor HitTestBehavior.translucent permite que la prueba de detección de toque del hijo pase al padre, pero sin activar onPointerDown del padre.

    Aquí está el código actualizado:

    Listener(
      onPointerDown: (event) {
        if (event.buttons == 2) {
          double dy = event.position.dy.ceilToDouble();
          double dx = event.position.dx.ceilToDouble();
          showMenu(
            context: context,
            position: RelativeRect.fromLTRB(dx, dy, dx, 0),
            items: [
              PopupMenuItem(child: const Text("Menú del Padre 1"), onTap: () {}),
            ],
          );
        }
      },
      child: ExpansionTile(
        initiallyExpanded: true,
        iconColor: Colors.white,
        leading: const Icon(Icons.book),
        title: const Text(
          "Nota",
          style: TextStyle(fontSize: 16.0, color: Colors.white),
        ),
        children: <widget>[
          Listener(
            onPointerDown: (event) {
              if (event.buttons == 2) {
                double dy = event.position.dy.ceilToDouble();
                double dx = event.position.dx.ceilToDouble();
                showMenu(
                  context: context,
                  position: RelativeRect.fromLTRB(dx, dy, dx, 0),
                  items: [
                    PopupMenuItem(child: const Text("Menú del Hijo 1"), onTap: () {}),
                    PopupMenuItem(child: const Text("Menú del Hijo 2"), onTap: () {}),
                  ],
                );
              }
            },
            behavior: HitTestBehavior.translucent, // Se agrega esta línea
            child: ListTile(
              title: Text(
                formatTitle(),
                style: TextStyle(color: Colors.white, fontSize: fontSize ?? 14.0),
              ),
              dense: true,
              onTap: () {},
            ),
          )
        ],
      ),
    )
    

    Con este cambio, onPointerDown del padre solo se activará cuando onPointerDown del hijo no se active.

Comments are closed.