Flutter StatefulWidget. Eventos

De MediaWiki
Revisión del 18:18 17 nov 2022 de Angelfg (discusión | contribuciones) (→‎GestureDetector)
(dif) ← Revisión anterior | Revisión actual (dif) | Revisión siguiente → (dif)
Ir a la navegación Ir a la búsqueda

Introducción

  • Veremos en la sección anterior de formularios como gestionar los diferentes eventos que se puedan producir en los elementos gráficos que conforman un formulario (botones, listas,...)
  • Pero puede ser necesario que queramos gestionar algún evento sobre un Widget el cual no tenga asociado ninguna función de gestión de eventos sobre el mismo en su constructor.
Veremos en este punto, cómo podemos implementar estos eventos.


  • Por otro lado, durante la ejecución de una aplicación Flutter, desde que el usuario decide lanzar la aplicación hasta que se muestra el primer Widget (pantalla), o cuando un usuario cambia de pantalla dentro de la misma aplicación, o cambia de aplicación y deja la nuestra en segundo plano...va pasando por una serie de estados sobre los que podemos ejecutar código cuando el Widget llegue al estado que estamos 'vigilando'.
En ejemplo de uso puede ser cuando estamos consumiendo recursos dentro de nuestra aplicación (por ejemplo, localización GPS, reproduciendo un archivo de audio / vídeo, conexión a una base de datos) y el usuario cambia de aplicación y deja la nuestra en segundo plano.
Al hacerlo, la aplicación pasa por el estado 'paused'. Nosotros, como programadores, podríamos en ese estado liberar los recursos, y cuando el usuario regresase a la aplicación (pasa por el estado 'resumed') volver a recuperar los recursos.
Podéis consultar en el siguiente enlace como controlar los diferentes estados:



  • Creamos una nueva página en la carpeta pages de nombre eventos_page.dart
En todas las páginas haremos lo mismo:
  • Importamos la librería de 'material' (recordar que existe un snippet que lo hace automático).
  • Creamos una clase (EventosPage) que derive de StatefulWidget. Se creará (si lo hacéis con un Snippet) una clase asociada que deriva de State.
  • Modificamos la clase State y en su métod build hacemos que devuelva un Scaffold con una Appbar (hacerlo con un Snippet)



InkWell

Nota: Para emplear este Widget es necesario que exista un Material Widget en alguno de sus ancestros en la jerarquía de Widget.


En el siguiente ejemplo vamos a ver las que normalmente vais necesitar emplear, como el click (onTap) o doble click (onDoubleTap), mantener presionado (onLongPress).


Flutter dart eventos 1.JPG


import 'package:flutter/material.dart';

class EventosPage extends StatefulWidget {
  const EventosPage({Key? key}) : super(key: key);

  @override
  _EventosPageState createState() => _EventosPageState();
}

class _EventosPageState extends State<EventosPage> {
  String _textoClick='Evento CLICK';
  String _textoDoubleClick = 'EVENTO DOUBLE CLICK';
  String _textoOnLongClick = 'EVENTO LONG CLICK';

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: Text('Xestión de Eventos'),
        ),
        body: ListView(
                children: [
                  _eventosSobreInkWell()
               ],
        )
    );
  }

  Widget _eventosSobreInkWell(){

    return Column(

      children: [
        InkWell(
          child: _crearContainer(texto: '$_textoClick',color: Colors.blue, fondo: Colors.yellow),
          onTap: () {
            setState(() {
              _textoClick = 'PULSASTE CON CLICK';
            });
          },
        ),
        InkWell(
          child: _crearContainer(texto: '$_textoDoubleClick',color: Colors.red, fondo: Colors.yellow),
          onDoubleTap: () {
            setState(() {
              _textoDoubleClick = 'PULSASTE DOUBLE CLICK';
            });
          },
        ),
        InkWell(
          child: _crearContainer(texto: '$_textoOnLongClick',color: Colors.green, fondo: Colors.yellow),
          onLongPress: () {
            setState(() {
              _textoOnLongClick = 'PULSASTE LONG CLICK';
            });
          },
        ),
      ],

    );

  }

  Widget _crearContainer({required String texto, required Color color, required Color fondo}) {
    return Container(
      margin: EdgeInsets.only(top:10),
      height: 70,
      width: 300,
      color: fondo,
      child: Text('$texto',textAlign: TextAlign.center,style: TextStyle(color: color,fontWeight: FontWeight.bold,fontSize: 30),),
    );

  }
}



GestureDetector

  • Más información en:


A diferencia del anterior Widget este:

  • No necesita tener un Widget ancestor de tipo Material.
  • No tiene el 'efecto visual' que tiene el InkWell cuando se produce el evento.
  • Tiene una mayor cantidad de eventos que podemos controlar, como deslizar los dedos sobre la pantalla,...


  • Modificaremos el ejemplo anterior para añadir dos contenedores que van gestionar el evento Click y el arrastrar el dedo sobre la pantalla en sentido horizontal.
Flutter dart eventos 2.JPG


import 'package:flutter/material.dart';

class EventosPage extends StatefulWidget {
  const EventosPage({Key? key}) : super(key: key);

  @override
  _EventosPageState createState() => _EventosPageState();
}

class _EventosPageState extends State<EventosPage> {
  String _textoClick='Evento CLICK';
  String _textoDoubleClick = 'EVENTO DOUBLE CLICK';
  String _textoOnLongClick = 'EVENTO LONG CLICK';

  String _textoClickGesture = 'Evento CLICK GESTURE';
  String _textoDragGesture = 'Evento DRAG';

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: Text('Xestión de Eventos'),
        ),
        body: ListView(
                children: [
                  _eventosSobreInkWell(),
                  _eventosSobreGestureDetector(),
               ],
        )
    );
  }

  Widget _eventosSobreInkWell(){

    return Column(

      children: [
        InkWell(
          child: _crearContainer(texto: '$_textoClick',color: Colors.blue, fondo: Colors.yellow),
          onTap: () {
            setState(() {
              _textoClick = 'PULSASTE CON CLICK';
            });
          },
        ),
        InkWell(
          child: _crearContainer(texto: '$_textoDoubleClick',color: Colors.red, fondo: Colors.yellow),
          onDoubleTap: () {
            setState(() {
              _textoDoubleClick = 'PULSASTE DOUBLE CLICK';
            });
          },
        ),
        InkWell(
          child: _crearContainer(texto: '$_textoOnLongClick',color: Colors.green, fondo: Colors.yellow),
          onLongPress: () {
            setState(() {
              _textoOnLongClick = 'PULSASTE LONG CLICK';
            });
          },
        ),
      ],

    );

  }


  Widget _eventosSobreGestureDetector(){

    return Column(

      children: [
        GestureDetector(
          child: _crearContainer(texto: '$_textoClickGesture',color: Colors.blue, fondo: Colors.yellow),
          onTap: () {
            setState(() {
              _textoClick = 'PULSASTE CON CLICK';
            });
          },
        ),
        GestureDetector(
          child: _crearContainer(texto: '$_textoDragGesture',color: Colors.green, fondo: Colors.yellow),
          onHorizontalDragUpdate: (detail){
            setState(() {
              _textoDragGesture = detail.delta.toString();
            });
          },
          onLongPress: () {
            setState(() {
              _textoOnLongClick = 'PULSASTE LONG CLICK';
            });
          },
        ),
      ],

    );

  }

  Widget _crearContainer({required String texto, required Color color, required Color fondo}) {
    return Container(
      margin: EdgeInsets.only(top:10),
      height: 70,
      width: 300,
      color: fondo,
      child: Text('$texto',textAlign: TextAlign.center,style: TextStyle(color: color,fontWeight: FontWeight.bold,fontSize: 30),),
    );

  }



}





Enlace a la página principal de la UD4

Enlace a la página principal del curso




-- Ángel D. Fernández González -- (2021).