latest

Introducción a la programación basada en widgets. Stateful widgets. Parte 2

En la lección anterior de este curso de Flutter aprendimos a construir nuestros propios StatefulWidget. Lo que os proponemos aquí es modificar la interfaz de usuario basada en StatelessWidget que hicimos en su correspondiente lección para que tenga un aspecto similar a lo siguiente:

Como podéis comprobar seguimos teniendo tres paneles contenedores heredados de Card (que en este caso será nuestro StatefulWidget). Cada uno tiene un RaisedButton, un icono y un widget Text que contará las veces que se ha pulsado el botón correspondiente. En el momento de la captura de la imagen de arriba "Me gusta" había sido pulsado 12 veces, "No me gusta" 17 veces y "Ni fu, ni fa" 11 veces. Además, como podéis apreciar, hemos jugado con colores diferentes para cada widget de la columna y con algunos elementos de paddings en el propio botón y entre los widgets botón-icono-texto.

Os pedimos que tratéis de recrear esta interfaz de usuario sin mirar el código que se os facilita a continuación.

import 'package:flutter/material.dart';

void main() {
  runApp(
    new MaterialApp(
      home: new MiStatelessWidget(), 
    ),
  );
}

class MiCardStateful extends StatefulWidget {

  // Propiedades estáticas
  final String titulo;
  final IconData datosIcono; 
  final num tamanyoIcono;
  final Color color;

  // Constructor
  MiCardStateful({this.titulo,this.datosIcono, this.tamanyoIcono=80.0, 
    this.color});

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

class _MiCardStatefulState extends State<MiCardStateful> {

  //Propiedades dinámicas:
  num _contador = 0;
  
  void _incrementContador(){
    setState(() {
     _contador++; 
    });
  }

  @override
  Widget build(BuildContext context) {
    return Container(
      padding: const EdgeInsets.only(top: 2.0),
      child: new Card(
        child:Container(
          padding: const EdgeInsets.all(15.0),
          child:Column(
            children: [
              RaisedButton(             
                child: Text(widget.titulo, style: TextStyle(
                  fontSize: 21.0,
                ),),
                onPressed: _incrementContador,
                color: widget.color,
                padding: EdgeInsets.all(16.0), // padding interno del botón
              ), 
              Padding( // padding entre boton e icono
                padding: EdgeInsets.all(3.0),
              ),
              Icon(
                widget.datosIcono,
                color: widget.color,
                size: widget.tamanyoIcono
              ),
              Padding(
                padding: EdgeInsets.all(3.0),
              ),
              Text(_contador.toString(),style: 
                TextStyle(
                  fontSize: 22.0,
                )
              ), // Otra manera: Text('$_contador')
            ],
          )
        )
      ),
    );
  }
}

class  MiStatelessWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) { 
    return Scaffold(
      appBar: new AppBar(
        title: new Text("¿Qué te parece el curso?"),
        backgroundColor: Colors.orangeAccent,
      ),
      body: new Center(
        child: new Column(
          crossAxisAlignment: CrossAxisAlignment.stretch,
          children: <MiCardStateful>[
            new MiCardStateful(
              titulo: "Me gusta",  
              color: Colors.greenAccent,  
              datosIcono: Icons.thumb_up,
              tamanyoIcono: 80.0
            ),
            new MiCardStateful(
              titulo: "No me gusta",        
              color: Colors.redAccent,
              datosIcono: Icons.thumb_down
            ),
            new MiCardStateful(
              titulo: "Ni fu, ni fa",        
              color: Colors.yellowAccent,
              datosIcono: Icons.thumbs_up_down,
              tamanyoIcono: 90.0
            ),
          ],
        )
      )
    );
  }
}

¿Fue fácil? o ¿fue difícil? ¿qué pensáis?...

Observad que nosotros hemos implementado MiCardStateful (que hereda de StatefulWidget) con varias propiedades estáticas (en este caso no hemos utilizado otros Widget como propiedades, como sí hicimos en la implementación anterior). Estas propiedades incluyen el título que encierra el RaisedButton, el nombre o datos del icono (ej.: Icons.thumb_up), una propiedad para el tamaño del icono y otra para el color tanto del RaisedButton como del Icon.

Por otro lado, nuestra clase para modelar el State asociado (_MiCardStatefulState) tiene una sola propiedad dinámica que es un contador (_contador) del numero de veces que se presiona el widget. El método sobreescrito build() de _MiCardStatefulState tampoco tiene mayor dificultad con widgets ya conocidos, intercalando otros de clase Padding. Observad como hacemos referencia a las propiedades estáticas del widget con (widget.propiedad) o usamos la propiedad dinámica que establece el State (_contador) directamente en un widget Text.

Hasta aquí los fundamentos sobre StatefulWidget, en las próximas lecciones veremos otros widgets básicos que pueden sernos de utilidad en nuestras GUIs (Entradas de texto, cuadros de diálogo modales y alertas, etc). Posteriormente, entraremos en profundidad en el uso de widgets más complejos.

Author image
Iván González is postdoctoral researcher at the Castilla-La Mancha University.
Ciudad Real (Spain)