Está en la página 1de 95

Traducido del inglés al español - www.onlinedoctranslator.

com

»UnDispositivo virtual Androides una descripción del hardware de un teléfono. el emulador


no funciona a menos que cree un AVD para que el emulador lo emule.
Cuando instala Android Studio, es posible que vea o no una opción para
instalar un AVD. Si lo hace, acepte la opción. Si no lo hace, está bien. Podrá
crear un montón de AVD cuando ejecute Android Studio.

Cuando instala Android Studio, el instalador puede ofrecerle la opción de crear un AVD
para que lo use. Si no se le ofreció esta opción, o si omitió la opción, puede crear un AVD
usando la herramienta AVD Manager. De hecho, puede crear varios AVD adicionales y
usar varios AVD diferentes para ejecutar y probar sus aplicaciones Flutter en el emulador
de Android.

Para abrir AVD Manager, vaya a la barra de menú principal de Android Studio y seleccione
Tools-AVD Manager. Las figuras 2-12 a 2-15 muestran los cuadros de diálogo que puede
encontrar en AVD Manager.

FIGURA 2-12:
la pagina inicial
de la AVD
Gerente.

FIGURA 2-13:
la primera pagina
en la creación de un

AVD nuevo.

48 PARTE 1preparándose
FIGURA 2-14:
la segunda pagina
en la creación de un

AVD nuevo.

FIGURA 2-15:
la pagina final
en la creación de un

AVD nuevo.

Soy reacio a enumerar las instrucciones para usar AVD Manager, porque el aspecto de la
herramienta AVD Manager cambia constantemente. Lo más probable es que lo que ve en la
pantalla de su computadora no se parezca mucho a las capturas de pantalla de mediados de
2019 en las Figuras 2-12 a 2-15.

CAPITULO 2Configuración de su computadora para el desarrollo de aplicaciones móviles 49


En lugar de darte instrucciones explícitas, mi consejo general al crear un nuevo AVD es
seleccionar los teléfonos o tabletas más nuevos y los niveles de API con números más altos, y
aceptar los valores predeterminados cada vez que tengas la tentación de jugar eeny-meeny-
miny-moe. Siga haciendo clic en Siguiente hasta que pueda hacer clic en Finalizar. Si no le gusta
el AVD que ha creado, siempre puede volver a abrir el Administrador de AVD y seleccionar
diferentes opciones para crear otro AVD. Cuando alcance el nivel de competencia en el que es
quisquilloso con las características de su AVD, probablemente conocerá muchas de las opciones
del Administrador de AVD y podrá elegir sabiamente.

Sobre la instalación de Flutter

A veces, cuando me siento mal, voy al médico. Si tiene problemas para ejecutar
aplicaciones y cree que su instalación de Flutter está enferma, puede llevar a Flutter al
médico. Así es cómo:

1.En Android Studio, inicie un nuevo proyecto de Flutter o abra un proyecto existente.
Para obtener ayuda con eso, consulte la sección "Ejecución de su primera aplicación" de este capítulo.

2.En la barra de menú principal de Android Studio, seleccione Herramientas-Aleteo-Doctor


Flutter.

Como resultado, la computadora le informa sobre el estado de su instalación


de Flutter.

El informe de Flutter Doctor no siempre es útil. Algunos de los hallazgos del informe
pueden ser falsas alarmas. Otros pueden ser difíciles de interpretar. Si ve algo que parece
un diagnóstico útil, pruébelo. Muchos de los consejos del médico implican abrir una
ventana de Terminal o Símbolo del sistema. Encontrarás consejos al respecto en la barra
lateral "Tu amigo, la línea de comandos".

TU AMIGO, LA LÍNEA DE MANDO


En la antigüedad, la única forma de comunicarse con una computadora era a través de la línea de
comandos. Tenías que saber exactamente qué escribir y, si te equivocabas, o no pasaba nada o pasaba
algo malo. En estos días, emite la mayoría de los comandos a través de un interfaz gráfica del usuario(
interfaz gráfica de usuario). Haga clic aquí, arrastre y suelte allí y haga todo tipo de cosas en un entorno
de ventana.

Pero, por desgracia, las interfaces de línea de comandos no han desaparecido. Algunas tareas aún requieren comandos

escritos a máquina largos y crípticos, y algunas personas prefieren escribir comandos en lugar de hacer clic en los botones.

50 PARTE 1preparándose
La mayoría de las instrucciones de este libro requieren señalar y hacer clic. Pero, aquí y allá, hay que
hacer las cosas a la antigua. Para ayudarlo a sobrevivir a la miseria inimaginable de escribir comandos
enigmáticos y propensos a errores, proporciono algunos consejos:

• No puede escribir comandos en cualquier lugar. Para comunicarse directamente con su


computadora, primero debe abrir la Terminal de su computadora (como se le conoce en el mundo
Mac) o el Símbolo del sistema (como se le conoce a los usuarios de Windows).

Si se está ejecutando Android Studio, puede abrir la Terminal de Mac o el símbolo del sistema de

Windows haciendo clic en el pequeño botón de la herramienta Terminal cerca de la parte inferior de la

ventana de Android Studio.

• En una Mac, siempre puede abrir la Terminal de Mac presionando Comando+espacio, escribiendo
Terminaly luego presionando Entrar.

En Windows, siempre puede abrir el Símbolo del sistema presionando Inicio, escribiendo
cmdy luego presionando Entrar.

• En cualquier momento, una ventana de terminal o símbolo del sistema tiene undirectorio de
trabajo. Por ejemplo, si el directorio de trabajo es /Usuarios/isaacnewton/Documentos,y
tu escribesmás miarchivo.txt,la computadora busca en el /Usuarios/isaacnewton/
Documentosdirectorio para un archivo llamadomiarchivo.txt.Si el /Usuarios/isaacnewton/
Documentosdirectorio tiene un archivo llamadomiarchivo.txt,la computadora muestra el contenido de

miarchivo.txten fragmentos del tamaño de una página.

(En Windows):Para averiguar qué directorio es el directorio de trabajo, mire el aviso o escribadiscos

compactos. Para cambiar el directorio de trabajo, escribadiscos compactosseguido del nombre del nuevo

directorio.

c:\Usuarios\isaacnewton\Documentos>discos

compactos c:\Usuarios\isaacnewton\Documentos

c:\Usuarios\isaacnewton\Documentos>cd c:\Usuarios\isaacnewton

c:\Usuarios\isaacnewton>discos

compactos c:\Usuarios\isaacnewton

• (En una Mac):Para averiguar qué directorio es el directorio de trabajo, escribapwd.Para cambiar el

directorio de trabajo, escribadiscos compactosseguido del nombre del nuevo directorio.

Isaacs-Air:Documentos isaacnewton$personas con

discapacidad /Usuarios/isaacnewton/Documentos

Isaacs-Air:Documentos isaacnewton$cd /Usuarios/isaacnewton

Isaacs-Air:~ isaacnewton$personas con

discapacidad /Usuarios/isaacnewton

CAPITULO 2Configuración de su computadora para el desarrollo de aplicaciones móviles 51


El contenido proporcionado pormédico aleteono pretende servir como sustituto del
consejo médico profesional. Busque el consejo de su médico de Flutter con cualquier
pregunta que pueda tener con respecto a una condición médica. Nunca ignore el consejo
médico profesional por algo que haya leído en el resultado de
médico aleteo.

División entre dispositivos


Si su computadora de desarrollo tiene suficiente potencia, puede ejecutar algunos dispositivos
virtuales de Android simultáneamente. En una Mac, puede ejecutar un simulador de iPhone mientras
se ejecutan sus dispositivos virtuales Android. Pero usar sus dispositivos virtuales y físicos puede ser
complicado. Esta sección le da algunos consejos.

Ejecutar aplicaciones en un dispositivo Android


Un lector de Minnesota escribe:

Estimado Barry,

He seguido todas tus instrucciones. Las cosas van bien hasta que intento ejecutar una aplicación. El

emulador de Android no funciona. ¿Qué tengo que hacer?

firmado,

Todavía helando en Minneapolis

Bueno, Sra. Freezing, el emulador que viene con Android Studio consume muchos
recursos en su computadora de desarrollo. Si es como yo y no siempre tiene el hardware
más reciente y potente, es posible que tenga problemas para ejecutar aplicaciones en el
emulador. Tal vez no vea la pantalla de inicio de Android o no vea su aplicación
ejecutándose cinco minutos después de que el emulador comience a ejecutarse. Si es así,
aquí hay varias cosas que puede probar:

»Hacer espuma, enjuagar, repetir.

Cierre el emulador y vuelva a iniciar su aplicación. A veces, la segunda o tercera vez


es un encanto. En raras ocasiones, mis primeros tres intentos fallan, pero mi cuarto
intento tiene éxito.

52 PARTE 1preparándose
»Si tiene acceso a una computadora con más RAM, intente ejecutar su aplicación
en eso.

Los caballos de fuerza importan.

»Si no tiene acceso a una computadora con más RAM, cierre todos los que no sean
programas esenciales en su computadora de desarrollo e intente ejecutar su
aplicación nuevamente.

»Pruebe con un AVD diferente.


La sección "Sobre la adición de dispositivos virtuales", anteriormente en este capítulo, le
indica cómo agregar un nuevo AVD a su sistema. Un AVD con una imagen del sistema x86
es mejor que un AVD con una imagen armeabi. (Afortunadamente, cuando un cuadro de
diálogo le permite elegir entre x86 y armeabi, no tiene que saber quéx86o armeabi
significa.)

»Luchar con la tecnología de virtualización.


Es posible que no desee comenzar por este agujero de conejo.

Cuando se ejecuta en un procesador Intel x86, el emulador de Android intenta usar algo
llamado Intel Virtualization Technology (VT) con Intel Hardware Accelerated Execution
Manager (HAXM). Si su computadora no se siente completamente cómoda con una
configuración de VT y HAXM, es probable que tenga problemas para usar el emulador de
Android.

¡No te desesperes! Intente instalar una imagen del sistema armeabi.

Finalmente, si su computadora puede usar VT y HAXM, y si desea ajustar estos


elementos en su computadora, continúe. Simplemente no me culpes si, un mes
después, de repente recuerdas que tu objetivo era aprender sobre Flutter.

La lista con viñetas anterior describe algunos remedios para problemas con el emulador
de Android Studio. Desafortunadamente, ninguna de las balas en esta lista es una bala de
plata. Si probó estos trucos y aún tiene problemas, puede intentar abandonar el
emulador que viene con Android Studio y ejecutar aplicaciones en un dispositivo "real".

Probar aplicaciones en un dispositivo físico


Puede omitir los dispositivos virtuales y probar sus aplicaciones en un teléfono físico, una
tableta o incluso una cafetera inteligente. Para hacerlo, debe preparar el dispositivo físico,
preparar su computadora de desarrollo y luego conectar los dos. Es bastante laborioso,
pero después de que lo haces por primera vez, se vuelve mucho más fácil. Esta sección
describe un resumen de los pasos que debe seguir.

CAPITULO 2Configuración de su computadora para el desarrollo de aplicaciones móviles 53


Para más detalles, visite estas páginas:

https://flutter.dev/docs/get-started/install/macos - deployment-to-ios-devices
https://flutter.dev/docs/get-started/install/windows - configure-su-dispositivo-android

Preparándose para probar en un dispositivo físico Android

Para probar su aplicación en un dispositivo Android, siga estos pasos:

1.En su dispositivo Android, habilite las Opciones de desarrollador.


En muchos dispositivos Android, puede hacer esto eligiendo Configuración - Acerca de. En la lista

Acerca de, toque el elemento Número de compilación siete veces. (Sí, siete veces). Luego presione el

botón Atrás para regresar a la lista de Configuración. En la lista Configuración, toque Sistema-

Opciones de desarrollador.

Algunas personas han informado que, después de tocar el elemento Número de


compilación siete veces, es útil girar la pata de un conejo sobre la cabeza tres veces.
Hasta ahora, no he podido replicar estos resultados.

2.En la lista de Opciones de desarrollador, active la depuración de USB.


Esto es lo que muestra uno de mis dispositivos cuando me meto con esta configuración:

La depuración de USB está destinada a fines de desarrollo.


Úselo para copiar datos entre su computadora y su dispositivo,

instale aplicaciones en su dispositivo sin notificación y lea los datos de registro.

Los administradores de Android me advierten que la opción de depuración USB puede


exponer mi dispositivo a malware.

En mi dispositivo, mantengo la depuración de USB activada todo el tiempo. Pero si te preocupa la

seguridad, desactiva la depuración de USB cuando no estés usando el dispositivo para desarrollar

aplicaciones.

3.(Solo para usuarios de Windows) Visitehttps://developer.android.com/studio/run/oem-


usb.htmlpara descargar el controlador USB de Windows de su dispositivo Android.
Instale el controlador en su computadora de desarrollo de Windows.

Mientras sigue el siguiente paso, vigile la pantalla de su dispositivo Android.

54 PARTE 1preparándose
4.Con un cable USB, conecte el dispositivo a la computadora de desarrollo.
No todos los cables USB son iguales. Unos cables, llamadoscables de datos, tienen
alambres y metal en lugares donde otros cables, llamadoscables de carga, no tienen nada
excepto plástico. Intente usar el cable USB que viene con su dispositivo. Si, como yo, no
puede encontrar el cable que vino con su dispositivo o no sabe qué cable vino con su
dispositivo, pruebe con más de un cable. Cuando encuentre un cable que funcione,
etiquételo. (Si el cablesiemprefunciona, etiquételo como "cable estable").

Cuando conecta el cable, ve un cuadro de diálogo emergente en la pantalla del dispositivo


Android. La ventana emergente le pregunta si desea permitir la depuración de USB.

5.Sí, permitir la depuración de USB.


Si no lo está buscando, puede perderse la ventana emergente para permitir la depuración de USB.
Asegúrese de buscar esta ventana emergente cuando conecte su dispositivo. Si definitivamente no
ve la ventana emergente, es posible que esté bien de todos modos. Pero si aparece el mensaje y
no respondes, definitivamente no estarás bien.

COMPROBACIÓN DE LA CONEXIÓN Y
ROTURA DE LA CONEXIÓN
Para saber si su teléfono Android está correctamente conectado a su computadora de
desarrollo, siga estos pasos:

1. Abra la Terminal en una Mac o el símbolo del sistema en Windows. Para obtener más

información, consulte la barra lateral anterior "Tu amigo, la línea de comandos".

2. Usa eldiscos compactoscomando para navegar a Androidplataforma-herramientasdirectorio. Soy

un usuario de computadoras rootin'-tootin', dos puños. En mi PC, escribo

cd %HOMEDRIVE%%HOMEPATH%\AppData\Local\Android\Sdk\plataforma-herramientas

En mi Mac, escribo

cd ~/Biblioteca/Android/sdk/plataforma-herramientas/

(continuado)

CAPITULO 2Configuración de su computadora para el desarrollo de aplicaciones móviles 55


(continuado)

3. Tipodispositivos adb. (En una Mac, escriba./dispositivos adb.)

Si la respuesta de su computadora incluye un número hexadecimal muy largo (como


2885046445FF097),ese número representa su dispositivo conectado. Por ejemplo, con un
teléfono en particular conectado, la respuesta de mi computadora es

dispositivo emulator-5554
dispositivo emulator-5556
2885046445FF097 dispositivo

Si ves la palabrano autorizadojunto al número hexadecimal largo, probablemente no


respondió bien a la pregunta "¿Permitir la depuración de USB?" en el Paso 5 de la sección
anterior "Preparación para probar en un dispositivo físico Android".

Si la respuesta de su computadora no incluye un número hexadecimal largo, es posible que


haya perdido el tren en uno de los otros pasos en esa sección anterior.

Eventualmente, querrá desconectar su dispositivo de la computadora de desarrollo. Busque alguna


referencia al dispositivo en el Explorador de archivos o en el Finder.

• Si no ve una referencia, probablemente pueda desconectar el cable USB del dispositivo de su


computadora.

• Si ve una referencia, intente expulsar el dispositivo.

Si intenta expulsar el dispositivo y ve el temido mensaje No es seguro quitar el dispositivo, comience siguiendo

los pasos 1 y 2 en esta barra lateral. A continuación, realice una de las siguientes acciones:

• En una Mac, escriba

. /adb matar-servidor

y luego presione Entrar.

• En Windows, escriba

adb matar-servidor

y luego presione Entrar.

Después de eso, verá el mensaje amistoso Safe to Remove Hardware.

56 PARTE 1preparándose
Preparándose para probar en un iPhone

Para probar su aplicación en un iPhone (o incluso en un iPad), debe usar una


computadora Apple. Si tienes una Mac, sigue estos pasos:

1.Visitarhttps://brew.shy sigue las instrucciones para instalar Homebrew en


tu computadora.

Homebrew es un administrador de paquetes de software de terceros para macOS y Linux. Puede


usarlo para instalar todo tipo de software, no solo herramientas de desarrollo de iPhone.

2.Abre la aplicación Terminal de tu Mac.


3.En la ventana de la aplicación Terminal, escriba los siguientes comandos,
uno tras otro:

actualización de cerveza

instalación de preparación --HEAD usbmuxd

elaborar enlace usbmuxd

brew install --HEAD libimobiledevice


brew install ideviceinstaller ios-deploy cocoapods
configuración de la cápsula

¿No fue divertido? Se tarda mucho tiempo en obtener respuestas y probablemente vea
mensajes de advertencia aterradores en el camino.

Las instrucciones de este paso están actualizadas a partir del 23 de agosto de 2019 a las 10:05 a.
m., horario de verano del Este. Después de ese momento, no hago promesas. Si te quedas
atascado, consulta la web o envíame un email.

4.Visitardesarrollador.apple.comy regístrese para obtener una membresía gratuita en el programa de


desarrolladores de Apple.

Después de estos tres pasos, su computadora de desarrollo está lista para funcionar. Sigue estos
pasos siempre que quieras probar una nueva aplicación de Flutter en un iPhone físico:

1.Conecte el teléfono físico a su computadora de desarrollo usando un cable de


datos USB.

No todos los cables son iguales. Apple pone un chip patentado en cada uno de los cables de su
iPhone. Si compra su cable a un proveedor externo, es posible que no pueda usarlo para
transferir una aplicación a su teléfono.

2.En Android Studio, abre tu nuevo proyecto Flutter.


3.Busque la ventana de la herramienta Proyecto, el panel que muestra un árbol de archivos y
carpetas.

CAPITULO 2Configuración de su computadora para el desarrollo de aplicaciones móviles 57


Encontrará la ventana de la herramienta Proyecto en el lado izquierdo de la ventana principal de

Android Studio. Si tiene problemas para encontrarlo, salte a la sección titulada "La ventana de la

herramienta Proyecto" en este capítulo.

4.Expande una de las ramas más altas del árbol para encontrar una rama secundaria llamadaiOS.
5.Haga clic derecho en eliOSsubdelegación. En el menú contextual resultante,
seleccione Flutter-Abra el módulo iOS en Xcode.

Como resultado, se inicia Xcode. Hay un árbol de archivos y carpetas en el lado izquierdo de la
ventana de Xcode.

6.En el árbol de archivos y carpetas, seleccione Runner. (Vea la Figura 2-16.)

FIGURA 2-16:
quien es baya
Burd?

7.Seleccione la pestaña Firma y capacidades cerca de la parte superior de la ventana de Xcode. (De
nuevo, consulte la Figura 2-16.)

La pestaña Firma y capacidades tiene una lista desplegable Equipo.

8.En la lista desplegable Equipo, seleccione Agregar una cuenta.


Como resultado, aparece un cuadro de diálogo Cuentas. Con su ID de Apple, automáticamente
pertenece a un equipo de desarrolladores: su equipo personal en el que usted es el único
miembro.

9.Haga lo que tenga que hacer en el cuadro de diálogo Cuentas y luego cierre el cuadro
de diálogo.

Como resultado, regresa a la pestaña Firma y capacidades.

10En la lista desplegable Equipo, seleccione su propio equipo.


11Cierra Xcode.
Eres bueno para ir.

58 PARTE 1preparándose
Pruebas en cualquier dispositivo físico (Android o iPhone)
Cuando esté listo para probar su aplicación en un dispositivo físico y haya conectado el dispositivo a su
computadora de desarrollo, consulte la lista desplegable Selector de destino en la barra de
herramientas de Android Studio. Cuando su computadora de desarrollo se comunica correctamente
con el dispositivo físico, el nombre del dispositivo aparece como uno de los elementos de esta lista
desplegable. (Consulte la Figura 2-17). Seleccione este elemento y luego haga clic en el icono Ejecutar.

FIGURA 2-17:
mi iPhone es
¡conectado!

Uso de Android Studio


Android Studio es una versión personalizada de IntelliJ IDEA, un IDE de propósito general
con herramientas para desarrollo de Java, desarrollo de C/C++, desarrollo de PHP,
modelado, gestión de proyectos, pruebas, depuración y mucho más.

En esta sección, obtendrá una descripción general de la ventana principal de Android Studio. Me
centro en las funciones más útiles que te ayudan a crear aplicaciones de Flutter, pero ten en cuenta
que Android Studio tiene cientos de funciones y muchas formas de acceder a cada función.

Empezando
Cada aplicación de Flutter pertenece a un proyecto. Puede tener docenas de proyectos en el
disco duro de su computadora. Cuando ejecuta Android Studio, cada uno de sus proyectos está
abierto o cerrado. Unabiertoproyecto aparece en una ventana (su propia ventana) en la pantalla
de su computadora. Acerradoproyecto no aparece en una ventana.

Varios de sus proyectos pueden estar abiertos al mismo tiempo. Puede cambiar entre
proyectos moviéndose de ventana a ventana.

A menudo me refiero a la ventana de un proyecto abierto como Android Studioventana


principal. Esto puede ser un poco engañoso porque, con varios proyectos abiertos a la vez,
tiene varias ventanas principales abiertas a la vez. En cierto modo, ninguna de estas ventanas
es más “principal” que las demás. Cuando yo escriboventana principal,Me refiero a la ventana
en cuyo proyecto Flutter estás trabajando en ese momento.

Si se está ejecutando Android Studio y no hay proyectos abiertos, Android Studio muestra su pantalla
de bienvenida. (Consulte la Figura 2-2.) La pantalla de Bienvenida puede mostrar algunos

CAPITULO 2Configuración de su computadora para el desarrollo de aplicaciones móviles 59


proyectos cerrados recientemente. Si es así, puede abrir un proyecto haciendo clic en su nombre en la
pantalla de bienvenida. Para una aplicación existente que no está en la lista de Proyectos recientes, puede
hacer clic en la opción Abrir un proyecto existente de Android Studio en la pantalla de bienvenida.

Si tiene proyectos abiertos, Android Studio no muestra la pantalla de bienvenida. En ese caso,
puede abrir otro proyecto seleccionando Archivo-Abrir o Archivo-Abrir reciente en la ventana de
un proyecto abierto. Para cerrar un proyecto, puede elegir Archivo-Cerrar proyecto, o puede
hacer lo que normalmente hace para cerrar una de las ventanas de su computadora. (En una
PC, haga clic en la X en la esquina superior derecha de la ventana. En una Mac, haga clic en el
pequeño botón rojo en la esquina superior izquierda de la ventana).

Android Studio recuerda qué proyectos estaban abiertos de una ejecución a la siguiente. Si hay algún
proyecto abierto cuando sale de Android Studio, esos proyectos se abrirán nuevamente (con sus
ventanas principales visibles) la próxima vez que inicie Android Studio. Puede anular este
comportamiento (para que solo aparezca la pantalla de bienvenida cada vez que inicie Android
Studio). En Android Studio en una computadora con Windows, comience seleccionando Archivo-
Configuración-Apariencia y comportamiento-Configuración del sistema. En Android Studio en una
Mac, seleccione Android Studio- Preferencias- Apariencia y comportamiento- Configuración del
sistema. En cualquier caso, desactive la casilla de verificación Reabrir último proyecto al iniciar.

la ventana principal
La ventana principal de Android Studio está dividida en varias áreas. Algunas de estas áreas pueden
aparecer y desaparecer según sus órdenes. Lo que sigue es una descripción de las áreas en la Figura
2-18, moviéndose desde la parte superior de la ventana principal hasta la parte inferior.

FIGURA 2-18:
la ventana principal
tiene varias zonas.

60 PARTE 1preparándose
Las áreas que ve en la pantalla de su computadora pueden ser diferentes de las áreas de la Figura 2-18. Por lo
general, eso está bien. Puede hacer que las áreas aparezcan y desaparezcan eligiendo ciertas opciones de
menú, incluida la opción Ver en la barra de menú principal de Android Studio. También puede hacer clic en los
pequeños botones de herramientas en los bordes de la ventana principal.

La parte superior de la ventana principal

El área superior contiene la barra de herramientas y la barra de navegación.

»losbarra de herramientascontiene botones de acción, como Abrir y Guardar todo. También


contiene el Selector de destino y el icono Ejecutar.

El Selector de destino es la lista desplegable cuya opción predeterminada es <sin dispositivos>. En


la Figura 2-18, el Selector de destino muestra el nombreiPhone XR.

El ícono Ejecutar es lo que parece un botón verde de Reproducir.

Puede leer más sobre estos elementos anteriormente, en la sección "Ejecución de su primera

aplicación" de este capítulo.

»La barra de navegación muestra la ruta a uno de los archivos en su proyecto Flutter.
Un proyecto de Flutter contiene muchos archivos y, en un momento determinado, trabajas en
uno de estos archivos. La barra de navegación apunta a ese archivo.

La ventana de la herramienta Proyecto

Debajo del menú principal y las barras de herramientas, verá dos áreas diferentes. El área de la
izquierda contiene elventana de herramientas de proyecto,que usa para navegar de un archivo a otro
dentro de su aplicación de Android.

En un momento dado, la ventana de la herramienta Proyecto muestra una de varias vistas posibles.
Por ejemplo, en la Figura 2-18, la ventana de la herramienta Proyecto muestra su vista del proyecto. En
la Figura 2-19, hago clic en la lista desplegable y selecciono la vista Paquetes (en lugar de la vista
Proyecto).

FIGURA 2-19:
Seleccionando

Vista de paquetes.

CAPITULO 2Configuración de su computadora para el desarrollo de aplicaciones móviles 61


Vista de paquetesmuestra muchos de los mismos archivos que la vista Proyecto, pero en la vista Paquetes, los
archivos se agrupan de manera diferente. Para la mayoría de las instrucciones de este libro, asumo que la
ventana de la herramienta Proyecto está en su vista predeterminada; a saber, Vista de proyecto.

Si Android Studio no muestra la ventana de la herramienta Proyecto, busque el botón de la herramienta


Proyecto, el pequeño botón que muestra la palabraProyectoen el borde izquierdo de la ventana principal.
Haga clic en el botón de la herramienta Proyecto. (¡Pero espere! ¿Qué sucede si no puede encontrar el
pequeño botón Proyecto? En ese caso, vaya al menú principal de Android Studio y seleccione Ventana -
Restaurar diseño predeterminado).

El área de redacción

El área a la derecha de la ventana de la herramienta Proyecto es elÁrea de edición. Cuando edita un


archivo de programa de Dart, el editor muestra el texto del archivo. (Consulte la Figura 2-18.) Puede
escribir, cortar, copiar y pegar texto como lo haría en otros editores de texto.

El área del Editor puede tener varias pestañas. Cada pestaña contiene un archivo que está abierto para editar.
Para abrir un archivo para editarlo, haga doble clic en la rama del archivo en la ventana de la herramienta
Proyecto. Para cerrar el archivo, haga clic en la pequeña x junto al nombre del archivo en la pestaña Editor.

la zona baja
Debajo de la ventana de herramientas Proyecto y el área del Editor hay otra área que contiene varias ventanas
de herramientas. Cuando no esté utilizando ninguna de estas ventanas de herramientas, es posible que no
vea esta área inferior.

En el área inferior, la ventana de herramientas que uso con más frecuencia es la ventana de herramientas
Ejecutar. (Consulte la parte inferior de la Figura 2-18.) La ventana de la herramienta Ejecutar aparece
automáticamente al hacer clic en el icono Ejecutar. Esta ventana de herramientas muestra información sobre
la ejecución de una aplicación Flutter. Si su aplicación no se ejecuta correctamente, la ventana de la
herramienta Ejecutar puede contener información de diagnóstico útil.

Puede hacer que aparezcan otras ventanas de herramientas en el área inferior haciendo clic en los botones de
herramientas cerca de la parte inferior de la ventana de Android Studio. Por ejemplo, cuando hace clic en el
botón de la herramienta Terminal, Android Studio muestra el Símbolo del sistema de Windows, la aplicación
Terminal de Mac u otra pantalla de comando basada en texto que especifique. Para obtener más información,
consulte la barra lateral anterior "Tu amigo, la línea de comandos".

Es posible que un botón de herramienta en particular no aparezca cuando no hay nada que pueda hacer con
él. Por ejemplo, es posible que el botón de la herramienta Ejecutar no aparezca hasta que presione el ícono
Ejecutar. No te preocupes por eso. El botón de la herramienta aparece siempre que lo necesite.

Terminando su recorrido por las áreas en la Figura 2-18. . . .

62 PARTE 1preparándose
la barra de estado

La barra de estado se encuentra en la parte inferior de la ventana de Android Studio.

La barra de estado le dice lo que está sucediendo ahora. Por ejemplo, si el cursor está en el carácter 37
de la línea 11 en el editor, verá11:37en algún lugar de la línea de estado. Cuando le dice a Android
Studio que ejecute su aplicación, la barra de estado contiene el mensaje más reciente de la ventana de
la herramienta Ejecutar.

El lavabo de la cocina

Además de las áreas que menciono en esta sección, pueden surgir otras áreas a medida que
surja la necesidad. Puede descartar un área haciendo clic en el icono Ocultar del área. (Vea la
Figura 2-20.)

FIGURA 2-20:
Ocultar el proyecto
área de la ventana de herramientas.

Ejecución de los programas de ejemplo de este libro

Este libro tiene docenas de aplicaciones Flutter de muestra, y todas están disponibles para descargar
desde el sitio web del libro:https://allmycode.com/Flutter.Puede ejecutar cualquiera de estos
programas como parte de una aplicación Android Studio Flutter. Esta sección tiene todos los detalles.

1.Inicie Android Studio.


Para la ejecución de su primera aplicación, necesita una conexión a Internet.

Lo que haga a continuación depende de lo que vea cuando inicie Android Studio.

2.Si ve la pantalla de bienvenida de Android Studio (consulte la Figura 2-2), seleccione Iniciar
un nuevo proyecto de Flutter.

Si ve otra ventana de Android Studio con una opción Archivo en la barra de menú
principal, elija Archivo-Nuevo-Nuevo proyecto Flutter en la barra de menú principal.

De cualquier manera, aparece el primer cuadro de diálogo para crear un nuevo proyecto de Flutter.

CAPITULO 2Configuración de su computadora para el desarrollo de aplicaciones móviles 63


3.Cree un nuevo proyecto de Flutter siguiendo los pasos 3 a 9 en la sección anterior de
este capítulo "Ejecución de su primera aplicación".

4.En la ventana de la herramienta Proyecto de Android Studio, busque una carpeta llamadaliberación.

Si necesita ayuda para encontrar esa ventana de herramientas, consulte la sección "Ventana de herramientas del

proyecto" anteriormente en este capítulo.

La ventana de la herramienta Proyecto contiene un árbol de carpetas y archivos. Expande una de las
ramas más altas del árbol para encontrar elliberacióncarpeta. Esteliberacióncontiene el código Dart de
su proyecto.

5.Haga clic derecho en el árboldardo principalrama y, a continuación, seleccione Eliminar.


Si Android Studio le solicita confirmación, haga clic en Aceptar. De una forma u otra, dale
dardo principalel viejo hehe-ho.

A lo largo de este libro, escribobotón derecho del ratóncomo si todo el mundo tuviera un ratón
con dos o más botones. Si es un usuario de Mac y su mouse tiene solo un botón, presione
Control + clic donde vea el términobotón derecho del ratón.

6.Asegúrate de haber descomprimido elFlutterForDummies_Listings. Código Postal


expediente.

Para obtener más información, consulte la barra lateral anterior "Archivos comprimidos".

Si no está seguro de dónde encontrar elFlutterForDummies_Listings.ziparchivo, busque primero en

una carpeta llamadaDescargas.La mayoría de los navegadores web ponen cosas dentro

Descargaspor defecto.

Safari en una Mac generalmente descomprime.Código PostalLos archivos se archivan automáticamente y los

navegadores de Windows (Internet Explorer, Firefox, Chrome y otros) no descomprimen los archivos .Código

Postalarchiva automáticamente. Para obtener información completa sobre los archivos de almacenamiento,

consulte la barra lateral anterior "Archivos de almacenamiento comprimidos".

7.En el Explorador de archivos o el Finder, navegue hasta el archivo sin comprimir


FlutterForDummies_Listadoscarpeta. Dentro de esa carpeta, busque el
ejemplo que desea ejecutar.

Si mira dentro de la descarga sin comprimir, verá archivos llamados


Aplicación0301.dardo, Aplicación0302.dardo,y así. Con algunas excepciones, los
números en estos nombres de archivo son números de capítulo seguidos de números de
lista. Por ejemplo, en el nombreApp0602.dardo,la06representa el Capítulo 6, y el02
representa la segunda lista de códigos de ese capítulo.

Para este experimento, le sugiero que busque elApp0201.dardoexpediente. (Ningún código aparece
en ninguna parte de este capítulo. Entonces, en este caso inusual,0201no se refiere a un proyecto cuyo
código se encuentra en el Listado 2-1).

8.Haga clic derecho en el elegidoaplicación####.dardoexpediente. Luego, en el menú contextual resultante,


seleccione Copiar.

64 PARTE 1preparándose
9.Haga clic derecho en el vacío del nuevo proyectoliberacióncarpeta. En el menú contextual resultante,
seleccione Pegar.

Si Android Studio muestra un cuadro de diálogo que ofrece pegar en un directorio en particular,
asegúrese de que el nombre completo del directorio termine enliberaciónLuego, presione Aceptar.

Ahora está listo para ejecutar uno de los ejemplos de este libro. ¡Ve a por ello!

En ocasiones, es posible que tenga más de un archivo en el archivo de su proyecto.liberacióncarpeta y más de


una aplicación en su proyecto. Si lo hace, es posible que al presionar el ícono Ejecutar no se ejecute la
aplicación que aparece en el área del editor de Android Studio. Para ejecutar la aplicación que se muestra en
el área del editor, busque la pestaña de esa aplicación en la parte superior del área del editor. Cuando hace
clic con el botón derecho en esa pestaña, verá una opción como Ejecutar 'App0201.dart'. Seleccione esa opción
y observe cómo se ejecuta el programa.

disfrutando de las reposiciones

La segunda vez que ejecuta un ejemplo particular de este libro, no tiene que seguir todos
los pasos de la sección anterior. Es fácil ejecutar un ejemplo una y otra vez. Puede realizar
cambios en el código y luego hacer clic en el ícono Ejecutar nuevamente. Eso es todo lo
que tienes que hacer.

Si cerró un proyecto y desea ejecutarlo nuevamente, simplemente vuelva a abrir el proyecto en


Android Studio y haga clic en el ícono Ejecutar. Para más detalles, consulte la sección “Puesta en
marcha” de este capítulo.

Si eres quisquilloso. . .
Después de seguir los pasos de la sección anterior, es posible que vea algunos marcadores de
error (subrayados rojos y ondulados) en la ventana de la herramienta Proyecto. El proyecto
Flutter de muestra de Android Studio describe algo llamadomi aplicación,pero el código que
copiaste en elliberacióncarpeta no hace mención deMiAplicación.Puede ejecutar este proyecto
una y otra vez sin corregir los subrayados rojos ondulados. Pero si desea solucionarlos,
simplemente siga estos pasos:

1.En la ventana de la herramienta Proyecto, expanda la rama etiquetadaprueba.


Dentro de esa rama, encontrará un archivo llamado widget_test.dart.

2.Borrar elwidget_test.dartexpediente.
Los subrayados rojos ondulados se han ido. ¡Problema resuelto!

CAPITULO 2Configuración de su computadora para el desarrollo de aplicaciones móviles sesenta y cinco


Las aplicaciones de este libro son aplicaciones de práctica. Nadie ejecuta estas aplicaciones para realizar un
trabajo real. (Esto incluye a Doris, a quien conoce en el Capítulo 7). Cuando desarrolla una aplicación real,
nunca debe ignorar el código en elpruebacarpeta. La prueba es una parte esencial del proceso de desarrollo
de software. Las pruebas exhaustivas son lo que hace que los programas funcionen de manera confiable.

Otra forma de deshacerse de los subrayados rojos ondulados es saltar a una máquina del
tiempo y rehacer las instrucciones en la sección "Ejecución de los programas de muestra de
este libro". Si ignora el paso 5 y no eliminadardo principal,no obtendrás esos subrayados
rojos. Pero es posible que tenga que lidiar con otros dos problemas. El comportamiento del
icono Ejecutar puede volverse un poco confuso. Además, puedes crear una grieta en el
continuo espacio-tiempo y convertirte en tu propio abuelo.

¿Fueron estos pasos de configuración divertidos o qué?

Siempre temo cualquier configuración de software que no sea completamente trivial. La


computadora de todos es diferente, y las instrucciones para la instalación de una aplicación no
pueden cubrir todos los escenarios posibles. Pero, después de poner en marcha el software, me
siento eufórico. Finalmente puedo comenzar a usar el software y disfrutar de la recompensa
por haber trabajado en los pasos de configuración.

Si todo el jibber-jabber en este capítulo lo llevó al punto en el que está listo para aprender
Flutter, ¡genial! Pero si todavía tiene dificultades para que el software funcione, escríbame. Mi
información de contacto está en la introducción del libro. Estaré encantado de ayudar.

66 PARTE 1preparándose
2
Flutter: A Burd's-
Vista de ojo
EN ESTA PARTE . . .

Escribiendo tu primer programa

Aprendiendo el lenguaje de programación Dart

Adición de texto e imágenes

Mejorar la apariencia de una aplicación


EN ESTE CAPÍTULO

»Ejecutando tu primera aplicación Flutter

»Adición de texto e imágenes

»Mejorar el diseño de su aplicación

Capítulo 3
"Hola" de Flutter
♪“Hola debo irme"♪
BERT KALMAR Y HARRY RUBY, CANTADAS POR GROUCHO MARX,
ENGALLETAS DE ANIMALES,1930

T
el palabraHolaes relativamente nuevo en el idioma inglés. Su primer uso conocido
impreso fue en Norwich, Connecticut,mensajeroen 1826. Alexander Graham Bell,
el inventor del teléfono, creía que las llamadas telefónicas debían comenzar con el
término¡Ay!pero, al parecer, Thomas Edison prefirióHola,y las primeras guías telefónicas
recomendaban la elección de Edison.

Según la leyenda, el primer programa de computadora que imprimió nada más que "¡Hola,
mundo!" fue escrito por Brian Kernighan, como parte de la documentación del lenguaje de
programación BCPL. La primera aparición pública de un programa de este tipo fue en el libro
de Kernighan y Ritchie de 1972,El lenguaje de programación C. En la actualidad, el término
programa hola mundo,o simplementehola programa,se aplica a cualquier código simple y sucio
para la primera exposición de alguien a un nuevo lenguaje o nuevo marco.

Este capítulo presenta un programa Flutter simple "Hola mundo" y varios adornos. Puede
ejecutar el código, diseccionarlo, cambiarlo y divertirse con él.

Lo primero es lo primero

El Listado 3-1 contiene su primera aplicación Flutter.

CAPÍTULO 3“Hola” de Flutter 69


LISTADO 3-1: ¡Ay, Maties!

importar 'paquete: flutter/material.dart';

principal() => ejecutarAplicación(Aplicación0301());

clase App0301 extiende StatelessWidget {


Compilación del widget (contexto BuildContext) {
devolver MaterialApp(
casa: Material(
niño: Texto("¡Hola mundo!"),
),
);
}
}

Puede descargar el código de esta aplicación (y el código de todos los demás listados en este
libro) desde mi sitio web. la URL eshttps://allmycode.com/Flutter.Puede encontrar
instrucciones detalladas para ejecutar el código en el Capítulo 2.

Si prefiere escribir el código usted mismo, siga estos pasos:

1.Crea un nuevo proyecto de Flutter.


Consulte el Capítulo 2.

Como de costumbre, Android Studio crea un archivo lleno de código Dart para ti. el nombre del archivo
esdardo principal

2.Asegúrese de que eldardo principalel código aparece en el editor de Android Studio.


Si no es así, expanda el árbol en la ventana de la herramienta Proyecto en el lado izquierdo de la

ventana principal de Android Studio. Buscarliberaciónrama y, dentro de laliberación


rama, ladardo principalrama. Haz doble clic en esodardo principalrama.

3.En el editor de Android Studio, elimine todos losdardo principalcódigo.


¡Qué liberador!

4.En el editor de Android Studio, escriba el código que ve en el Listado 3-1.


EL LENGUAJE DE PROGRAMACIÓN DE DART DISTINGUE A LAS MAYÚSCULAS.Si cambia una letra
minúscula en una palabra a una letra mayúscula, puede cambiar el significado de la palabra.
CAMBIAR el caso puede hacer que la palabra entera pase de tener sentido a no tener sentido.
En la primera línea del Listado 3-1, no puede reemplazarimportarconImportar.SI LO HACE,
TODO EL PROGRAMA DEJA DE FUNCIONAR. ¡Pruébelo y compruébelo usted mismo!

La Figura 3-1 le muestra el producto terminado.

70 PARTE 2Aleteo: una vista de Burd's-Eye


FIGURA 3-1:
Una aplicación Flutter es

listo para correr.

5.Ejecute su nueva aplicación.


Para obtener instrucciones detalladas sobre cómo iniciar una ejecución, consulte el Capítulo 2.

La Figura 3-2 le muestra lo que ve cuando ejecuta la aplicación Flutter en el Listado 3-1. La aplicación
se ve bastante mal, pero al menos puedes ver el pequeño¡Hola Mundo!en la esquina superior
izquierda de la pantalla. Me ocuparé de los aspectos estéticos de la aplicación más adelante en este
capítulo.

FIGURA 3-2:
Ejecutando el código
en el Listado 3-1.

Es posible que vea marcadores rojos en el editor de Android Studio. Si lo hace, coloque el cursor
sobre un marcador y lea la explicación que aparece. Algunas explicaciones son fáciles de
entender; otros no lo son. Cuanta más práctica tenga en la interpretación de estos mensajes,
más hábil se volverá para solucionar los problemas.

Otra cosa que puede intentar es seleccionar la pestaña Dart Analysis en la parte inferior de la
ventana principal de Android Studio. Esta pestaña enumera muchos de los puntos de su
proyecto que contienen código cuestionable. Para cualquier elemento de la lista, un icono rojo
indica un error, algo que debe corregirse. (Si no lo soluciona, su aplicación no podrá
ejecutarse). Cualquier otro ícono de color indica una advertencia, algo que no evitará que su
código se ejecute, pero que podría valer la pena considerar.

En las próximas secciones, desmontaré el código del Listado 3-1. Exploro el código desde
muchos puntos de vista. Explico lo que hace el código, por qué hace lo que hace y qué
podría hacer de manera diferente.

CAPÍTULO 3“Hola” de Flutter 71


¿De que trata todo esto?
Cuando observa el Listado 3-1, puede ver palabras, puntuación y sangría, pero eso no es lo que
ven los desarrolladores experimentados de Flutter. Ellos ven el contorno general. Ven grandes
ideas en oraciones completas. La Figura 3-3 le muestra cómo se ve el Listado 3-1 para un
desarrollador experimentado.

FIGURA 3-3:
El panorama.

Un programa de Flutter es como un conjunto de muñecas rusas matryoshka. Es una cosa dentro de
una cosa dentro de otra cosa, y así sucesivamente, hasta llegar a un punto final. (Consulte la Figura
3-4.)

FIGURA 3-4:
El look en capas.

72 PARTE 2Aleteo: una vista de Burd's-Eye


El listado 3-1 tiene algunosTextodentro de un pedazo deMaterialque está, a su vez, dentro de un
MaterialApp.Las palabrasTexto, Material,yMaterialAppiniciar comandos para
construir cosas En la terminología del lenguaje Dart, las palabrasTexto, Material,y
MaterialAppson los nombres dellamadas al constructor. Aquí está la historia interna:

»El código
Texto("¡Hola mundo!")

es unllamada al constructor. Cuando Flutter ejecuta este código, construye unTexto


objeto. QueTextoobjeto contiene las palabras¡Hola Mundo!

»El código
Material(
niño:Texto("¡Hola mundo!"),
)

es otra llamada al constructor. Cuando Flutter ejecuta este código, construye un


Materialobjeto. QueMaterialel objeto contiene lo antes mencionadoTexto
objeto. (Vea la Figura 3-5.)

FIGURA 3-5:
Cada constructor
llamada crea un
objeto.

AMaterialobjeto tiene algunas de las características que podría tener el material físico,
como una pieza de tela. Tiene una forma determinada. Puede estar elevado desde la
superficie debajo de él. Puedes moverlo o pellizcarlo. Por supuesto, el fondo de la figura
3-2 no se parece mucho a un trozo de tela. Pero imitar la textura de la tela no es el objetivo
de Material Design. El objetivo de Material Design es crear un lenguaje para describir el
estado de los componentes en la pantalla de un usuario y describir cómo estos
componentes se relacionan entre sí.

Para conocer la primicia sobre Material Design, visitehttps://material.io/.

CAPÍTULO 3“Hola” de Flutter 73


»El código
MaterialAplicación(

hogar:Material(
niño: Texto("¡Hola mundo!"),
),
)

es otra llamada al constructor. Cuando Flutter ejecuta este código, construye un


MateralAppcuya pantalla de inicio es laMaterialobjeto. (Consulte la Figura 3-3.)

Aquí hay una manera de resumirlo todo:

En el Listado 3-1, elMaterialAppobjetotiene unMaterialobjeto, y elMaterial


objetotiene unTextoobjeto.

En esa oración, el uso aparentemente inocente de las palabras "tiene un" es importante. Para obtener
más detalles, consulte la sección posterior "Un breve tratado sobre la interioridad".

Para comprender el código del Listado 3-1, debe saber dónde comienzan y terminan los pares de
paréntesis. Pero encontrar las coincidencias entre paréntesis abiertos y cerrados no siempre es fácil.
Para ayudar con este problema, Android Studio tiene algunos trucos bajo la manga virtual. Si coloca el
cursor cerca de un carácter de paréntesis, Android Studio resalta el paréntesis correspondiente.
Además, puede visitar el cuadro de diálogo Configuración o Preferencias de Android Studio. (En
Windows, seleccione Archivo- Configuración. En una Mac, seleccione Android Studio- Preferencias). En
ese cuadro de diálogo, seleccione Editor-General- Apariencia y coloque una marca de verificación en la
casilla de verificación Mostrar etiquetas de cierre en el código fuente de Dart. Después de descartar el
cuadro de diálogo, Android Studio muestra comentarios que marcan el final de muchas llamadas al
constructor. (Observe las etiquetas
// Materialy //MaterialAppen la Figura 3-6.)

FIGURA 3-6:
Cierre útil
etiquetas.

74 PARTE 2Aleteo: una vista de Burd's-Eye


Los parámetros de un constructor
Cada llamada al constructor tiene una lista deparámetros(generalmente llamado unlista de
parámetros). En el Listado 3-1, la lista de parámetros de cada constructor tiene solo un parámetro.
(Consulte la Figura 3-7.)

FIGURA 3-7:
Llamadas de constructor
tener parámetros.

Las llamadas de constructor pueden tener muchos parámetros o no tener parámetros. Tomemos, por
ejemplo, elTextollame en el Listado 3-1. En ese código, el parámetro "¡Hola Mundo!"
proporciona información a Dart, información que es específica delTextowidget que Dart
está construyendo. Intenta cambiarTexto("¡Hola mundo!")aText("¡Hola mundo!",
textScaleFactor: 4.0).Cuando guarda el nuevo código, Android Studio realiza un reinicio
en caliente que cambia el aspecto de la aplicación en su emulador. (Consulte la Figura
3-8.)

FIGURA 3-8:
Una aplicación fea para

ilustrar el
textScaleFactor
parámetro
efecto.

El Capítulo 1 describe la diferencia entre las funciones de reinicio en caliente y recarga en caliente de Flutter. Ambas

funciones aplican actualizaciones a una aplicación mientras se ejecuta. Para hacer un reinicio en caliente, simplemente

guarde su código. Para realizar una recarga en caliente, presione el ícono Ejecutar cerca de la parte superior de la

ventana principal de Android Studio.

La llamada del constructor

Texto("¡Hola mundo!", textScaleFactor: 4.0)

CAPÍTULO 3“Hola” de Flutter 75


contiene dos tipos de parámetros:

»"¡Hola Mundo!"es un parámetro posicional.


Aparámetro posicionales un parámetro cuyo significado depende de su posición en la lista
de parámetros. Cuando creas un nuevoTextoobjeto, los caracteres a mostrar siempre
deben aparecer primero en la lista. Puede ver esto por sí mismo cambiando la llamada del
constructor al siguiente código no válido:

Texto(textScaleFactor: 4.0, "¡Hola mundo!")//¡Código incorrecto!

En este código, el posicional "¡Hola Mundo!"El parámetro no viene primero en la lista.


Entonces, si escribe esta línea en el editor de Android Studio, el editor marca esta línea con
un feo indicador de error rojo. ¡Rápido! Cámbielo de nuevo para que el "¡Hola Mundo!"¡El
parámetro es lo primero! ¡No querrás que Android Studio se lleve una mala impresión de
ti!

»factor de escala de texto: 4.0es un parámetro con nombre.


Aparámetro nombradoes un parámetro cuyo significado depende de la palabra que precede a los dos

puntos. ATextoLa llamada al constructor puede tener muchos parámetros con nombre diferentes, como

factor de escala de texto, estilo,ylineas maximas.Puede escribir los parámetros con nombre en
cualquier orden, siempre que estén después de cualquiera de los parámetros posicionales.

Cuando suministras untextScaleFactorparámetro, el parámetro le dice a Flutter qué tan


grande debe ser el texto. (Consulte la Figura 3-8.) Cuando no proporciona un
textScaleFactorparámetro, Flutter usa el factor predeterminado 1.0.

El tamaño del texto depende de algunas cosas, como eltextScaleFactor


y unestilotamaño de fuente del parámetro. Por ejemplo, el siguiente código hace
¡Hola Mundo!dos veces más grande que en la figura 3-8.

Texto("¡Hola mundo!", textScaleFactor: 4.0,


estilo: Estilo de texto (tamaño de fuente: 28.0))

La aplicación que se muestra en la Figura 3-8 ya tienetextScaleFactor4.0. Pero tiene el tamaño de


fuente predeterminado, que es 14.0. Como 28,0 es dos veces 14,0, eltamaño de fuente: 28.0
parámetro duplica el tamaño del texto.

Una nota sobre la puntuación


En Dart, usa comas para separar los parámetros de un constructor entre sí. Y, para todas
las listas de parámetros excepto las más simples, finaliza la lista con un coma final.

76 PARTE 2Aleteo: una vista de Burd's-Eye


devolver MaterialApp(
casa: Material(
niño: Texto("¡Hola mundo!"),//Coma final después del parámetro secundario
), // Coma final después del parámetro de inicio
);

Sin comas finales, su código se ejecuta como se esperaba. Pero la siguiente sección le
dice cómo puede obtener Android Studio para que su código se vea bien. Y, sin comas
finales, Android Studio no da lo mejor de sí.

Un par de barras (//) tiene un significado especial en Dart. Para saber de qué se trata, consulte el
Capítulo 4.

No cedas, simplemente sangra


Eche otro vistazo al Listado 3-1 y observe cómo algunas de las líneas están sangradas.
Como regla general, si una cosa está subordinada a otra, su línea de código tiene más
sangría que esa otra cosa. Por ejemplo, en el Listado 3-1, elMaterialApp
objeto contiene elMaterialobjeto, por lo que elcasa: Materiala línea está más sangrada
que ladevolver MaterialApplínea.

Aquí hay dos hechos a tener en cuenta:

»En un programa Dart, la sangríano esnecesario.


»En un programa Dart, la sangríaesnecesario.

¡Esperar! ¿Cuáles son esos dos hechos de nuevo?

Si cambia la sangría en un programa Dart, el programa aún se ejecuta. Aquí hay una
reelaboración válida del código en el Listado 3-1.

// No hagas esto. Es un código mal sangrado.


importar 'paquete: flutter/material.dart';

principal() => ejecutarAplicación(Aplicación0301());

clase App0301 extiende StatelessWidget {


Compilación del widget (contexto BuildContext) {

devolver MaterialApp(
casa: Material(

CAPÍTULO 3“Hola” de Flutter 77


niño: Texto("¡Hola mundo!"),
),
);
}
}

Cuando le pide a Android Studio que ejecute este código mal sangrado, funciona. Android
Studio ejecuta diligentemente el código en su dispositivo virtual o físico. Pero ejecutar
este código no es suficiente.Este código mal sangrado es horrible. Es casi imposible de
leer.La sangría, o la falta de ella, no le da ninguna indicación de la estructura del
programa. Tienes que vadear las palabras para descubrir que elMaterial
el widget está dentro delMateralAppartilugio. En lugar de mostrarte la estructura de la aplicación de
un vistazo, este código hace que tus ojos deambulen sin rumbo en un mar de comandos
aparentemente no relacionados.

La buena noticia es que no tiene que aprender a sangrar su código. Android Studio puede
hacer la sangría por ti. Así es cómo:

1.Abra el cuadro de diálogo Configuración o Preferencias de Android Studio.


En Windows, seleccione Archivo - Configuración.

En una Mac, seleccione Android Studio - Preferencias.

2.En ese cuadro de diálogo, seleccione Idiomas y marcos-Flutter y luego coloque una marca
de verificación en la casilla de verificación Format Code on Save.

La marca de verificación le dice a Android Studio que corrija la sangría de su código cada vez
que guarde su trabajo.

Mientras lo hace, también podría poner una marca de verificación en la siguiente casilla de verificación: la casilla

de verificación Organizar importaciones al guardar.

3.Seleccione Aceptar para descartar el cuadro de diálogo.

¡Hazá! Cuando ejecuta el código, o simplemente lo guarda, Android Studio


corrige la sangría del código.

Si desea tener más control sobre el comportamiento de Android Studio, no juegue con el
cuadro de diálogo Configuración o Preferencias. En su lugar, cada vez que desee que se corrija
la sangría, coloque el cursor en el panel Editor y luego elija Code-Reformat Code en el menú
principal de Android Studio.

De una forma u otra, por favor sangra tu código correctamente.

78 PARTE 2Aleteo: una vista de Burd's-Eye


Clases, objetos y widgets
Dart es un lenguaje orientado a objetos, por lo que Dart tiene cosas llamadas objetos y
clases. El listado 3-1 contiene los nombres de muchas clases, comoApp0301, apátrida
Widget, Widget, BuildContext, MaterialApp, Material,yTexto.es justo decir
que casi todas las palabras del Listado 3-1 que comienzan con una letra mayúscula son el
nombre de una clase.

No es necesario saber mucho sobre programación orientada a objetos para comprender el


papel de estas palabras en el Listado 3-1, pero es útil tener en cuenta algunos datos:

»Un objeto es una cosa de algún tipo. Cada objeto pertenece a un particular.
clase de cosas.

La palabraTextoes el nombre de una clase de cosas, cosas que contienen caracteres que se
mostrarán en la pantalla. Por sí sola, una clase no hace mucho. El hecho de que Flutter tenga
unTextoclass no significa nada para una aplicación que muestra imágenes y no caracteres.
Puedes hablar de la clase de todos los unicornios, pero nunca he visto un unicornio en mi
patio delantero.

Por el contrario, la llamada al constructorTexto("¡Hola mundo!")construye un objeto real.


Ese objeto aparece en la pantalla del usuario. por ejemplo, unTextoobjeto que contiene
las palabras¡Hola Mundo!aparece en la Figura 3-2. Puedes referirte a ese objeto como un
instanciadelTextoclase.

En cualquier aplicación en particular, no puede construirTextoinstancias, unoTexto


ejemplo, o muchosTextoinstancias. Lo mismo ocurre con clases comoWidgety
Materialy casi todas las demás clases.

»Ser una instancia de una clase puede convertirlo automáticamente en un


ejemplo de una clase más grande.

Cada instancia de la clase Cat es, por definición, una instancia de la clase Animal. (Si
eso no fuera cierto, millones de videos de YouTube no existirían). ¿Y qué pasa con la
clase Animal? Cada instancia de la clase Animal es una instancia de la clase
LivingThing. (Vea la Figura 3-9.)

FIGURA 3-9:
tengo que mencionar
gatos en alguna parte
en este libro.

CAPÍTULO 3“Hola” de Flutter 79


De la misma manera, cada instancia de FlutterTextoLa clase es, por definición, una
instancia de Flutter.Widget sin estadoclase. Y, a su vez, cada instancia de laWidget
sin estadola clase es una instancia de FlutterWidgetclase. Así que cada
Textoinstancia es también unWidgetinstancia. (Consulte la Figura 3-9.)

»En Flutter, casi todos los objetos son, de una forma u otra, una instancia de
laWidgetclase.

Informalmente, un widget es un componente en la pantalla de un usuario. Flutter lleva


esta idea a otro nivel, con cada parte de la interfaz de usuario (elTextoejemplo, el
Materialejemplo, e incluso elMaterialAppejemplo) siendo un widget por derecho
propio.

En el Listado 3-1,aplicación0301es el nombre de una clase. En la linea

principal() => ejecutarAplicación(Aplicación0301());

el términoAplicación0301()es otra llamada al constructor. Esta llamada construye una


instancia delaplicación0301clase.

La línea

clase App0301 extiende StatelessWidget

y todo el código debajo es eldeclaracióndelaplicación0301clase. La declaración le


dice a Dart qué tipo de clase es y qué tipo de cosas puede hacer con la clase. En
particular, la palabraextiendeen esa primera línea hace cualquier instancia de la
aplicación0301la clase sea una instancia de laWidget sin estadoclase. Eso es todo lo que tienes que
hacer para haceraplicación0301instancias sean instancias de laWidget sin estadoclase.

Ahora tiene varios términos con significados sutilmente diferentes:clase,objeto, instancia,


yartilugio. En el Listado 3-1, el códigoTexto("¡Hola mundo!")construye algo, pero
¿exactamente qué tipo de cosa construye ese código?

»Desde el punto de vista del lenguaje Dart,Texto("¡Hola mundo!")


construye un objeto.

En la terminología de Dart, lo llamas una instancia de laTextoclase.

»Desde el punto de vista de Flutter,Texto("¡Hola mundo!")crea un widget.


Es una instancia de laTextoclase y por lo tanto (. . . culpa por asociación. . .)
una instancia de laWidget sin estadoclase y una instancia de laWidgetclase.

Para más de mi parloteo sobre objetos, clases y widgets, vea el Capítulo 7.

80 PARTE 2Aleteo: una vista de Burd's-Eye


Un breve tratado sobre la “interioridad”
En un programa Dart, puede encontrar widgets dentro de otros widgets. (Consulte la
Figura 3-4.) En el mismo programa Dart, encontrará clases dentro de otras clases.
(Consulte la Figura 3-9.) Estos dos tipos de "interioridad" no son lo mismo. De hecho,
estos dos tipos de “adentro” tienen poco que ver entre sí.

En la Figura 3-3, unTextowidget es el hijo de unMaterialartilugio. Estenosignifica que un


Textoinstancia es también una instancia de laMaterialclase. Para comprender la
diferencia, piense en dos tipos de relaciones: relaciones "es un" y relaciones "tiene un".

»Las relaciones que describo en la sección "¿De qué se trata?" sección son
relaciones “tiene una”.

En el Listado 3-1, elMaterialAppobjeto tiene unMaterialobjeto dentro de él, y el


Materialobjeto tiene unTextoobjeto dentro de él.

No hay nada especial en las relaciones "tiene un". Puede haber relaciones
"tiene un" en un corral. Un gato tiene un ratón y el ratón tiene un trozo
de queso.

»Las relaciones que describo en el apartado anterior “Clases, objetos y


La sección "widgets" son relaciones "es un".

En cada programa de Flutter, cadaTextoel objeto es unWidget sin estadoobjeto y, a su


vez, cadaWidget sin estadoel objeto es unWidgetobjeto.

En un corral, cada Gato es un Animal y, a su vez, cada Animal es un Ser Vivo.

No tendría sentido decir que un Gato es un Ratón, o que unMaterialel objeto es un


Textoobjeto. De la misma manera, no es correcto decir que todo Gato tiene un Animal, o
que todoTextoobjeto tiene unWidget sin estadoobjeto. Los dos tipos de relaciones,
"tiene un" y "es un", son bastante diferentes.

Si tiene hambre de terminología que sea más formal que "tiene un" y "es un", tengo algo
para usted:

»Una cadena de cosas conectadas por la relación "tiene un" se llama


jerarquía de composición.

Por frívolo que sea, el diagrama de la figura 3-4 ilustra una jerarquía de
composición.

»La cadena de cosas conectadas por la relación "es un" se llama


jerarquía de herencia.

Los diagramas en la Figura 3-9 son parte de la jerarquía de clases de Flutter.

CAPÍTULO 3“Hola” de Flutter 81


¿No te sientes mejor ahora que tienes estos términos elegantes para lanzar?

En Flutter, casi todo se llama "widget". Muchas clases son widgets. Cuando una clase es un
widget, las instancias de la clase (cualquier objeto construido a partir de esa clase) también se
denominan widgets.

La documentación es tu amiga.
Quizás te estés preguntando cómo vas a memorizar todos estos nombres:Texto,
StatelessWidget, MaterialApp,y probablemente miles más. Siento decirlo, estás
haciendo la pregunta equivocada. No memorizas nada. Cuando usa un nombre con la
suficiente frecuencia, lo recuerda de forma natural. Cuando no recuerda un nombre, lo
busca en los documentos en línea de Flutter. (A veces, no está seguro de dónde buscar el
nombre que desea. En ese caso, debe hurgar un poco).

Para ver lo que quiero decir, apunta tu navegador web ahttps://api.flutter.dev/flutter/


widgets/Text-class.html.Cuando lo haga, verá una página con información sobre elTexto
class, algo de código de muestra y algunas otras cosas. (Vea la Figura 3-10.)

FIGURA 3-10:
Información útil sobre
la clase Texto.

En la esquina superior derecha de la página, encontrará una lista deTextoconstructores En la


Figura 3-10, hay dos posibilidades:Textoyrico.Si selecciona elTextoenlace, verá una página que
describe elTextollamada del constructor. (Vea la Figura 3-11.)

Esta página enumera los parámetros en la llamada del constructor y proporciona otra
información útil.

82 PARTE 2Aleteo: una vista de Burd's-Eye


FIGURA 3-11:
El texto
llamada del constructor.

En la página de la Figura 3-11, observe cómo todos menos uno de los parámetros del
constructor están encerrados entre un par de llaves. El parámetro que no está entre llaves (es
decir,cadena de datos)es el único parámetro posicional del constructor. Cada uno de los
parámetros dentro de las llaves (incluyendofactor de escala de texto doble)es un parámetro
con nombre.

Siempre puedes contar con la documentación de Flutter para saber qué tipos de objetos
puedes y no puedes poner dentro de otros objetos. Por ejemplo, el siguiente código está
condenado al fracaso:

devolver MaterialApp(
niño: Texto("¡Hola mundo!"),//¡No hagas esto!
);

Está condenado porque, según los documentos de Flutter, elMaterialAppel constructor no


tiene un parámetro llamadoniño.

Hacer que las cosas se vean mejor

La aplicación que se muestra en la Figura 3-2 se ve bastante mal. Las palabras¡Hola Mundo!están
metidos contra la esquina superior izquierda de la pantalla. Afortunadamente, Flutter ofrece una
manera fácil de arreglar esto: rodeas elTextoartilugio con unCentroartilugio. Como su nombre lo
indica, elCentrowidget centra lo que sea que esté dentro de él.

CAPÍTULO 3“Hola” de Flutter 83


La palabraCentroes el nombre de una clase, por lo que cualquier objeto construido a partir de
esa clase se denomina instancia de esa clase. En un término como “Centroartilugio”, la palabra
artilugiosugiere que algo comoCentro (algo para ayudar a administrar el diseño de la pantalla)
es un componente de algún tipo. Una pieza deTextoen la pantalla hay un componente, una
pieza deMaterialen la pantalla es un componente, y unCentroel objeto también es un
componente. Aunque unCentrowidget no se enciende en algún lugar de la pantalla, unCentro
widget sigue siendo un componente. Parte de la gran fortaleza de Flutter es que trata todas las
cosas de la misma manera. Cuando tantas cosas son widgets, tantas cosas pueden servir como
parámetros en los constructores de otras cosas. Las personas que inventan nombres para
funciones de programación lo llaman elcomponibilidad característica, y la composición es una
característica muy agradable de tener.

Tienes algunas maneras de rodear unTextocódigo del widget con unCentrocódigo del widget.
Una forma es empujar el cursor en algún lugar dentro del editor de Android Studio, comenzar a
escribir y esperar que navegue por la maraña de paréntesis correctamente. Una mejor manera
es hacer lo siguiente:

1.Coloque el cursor sobre la palabraTextoen el editor


2.Presione Alt+Entrar.
Como resultado, aparece una lista desplegable.

3.En la lista desplegable, seleccione Widget central.


El Listado 3-2 le muestra lo que obtiene.

LISTADO 3-2: Centrar el texto

importar 'paquete: flutter/material.dart';

principal() => ejecutarAplicación(Aplicación0302());

clase App0302 extiende StatelessWidget {


Compilación del widget (contexto BuildContext) {
devolver MaterialApp(
casa: Material(
niño:Centro(
niño: Texto("¡Hola mundo!"),
),
),
);
}
}

84 PARTE 2Aleteo: una vista de Burd's-Eye


En el Listado 3-2, elMaterialwidget tiene unCentroniño widget, que, a su vez, tiene un
Textoniño widget. Puedes pensar en elTextowidget como el nieto del
Materialartilugio.

Flutter admite el reinicio en caliente. Después de agregar elCentrocódigo al programa en


el editor de Android Studio, guarde los cambios presionando Ctrl+S (en Windows) o
Cmd+S (en una Mac). Si el programa del Listado 3-1 ya se estaba ejecutando, Flutter aplica
sus cambios y actualiza la pantalla del emulador casi de inmediato.

En algunas situaciones, el reinicio en caliente no funciona. En lugar de actualizar su aplicación, Android Studio
muestra un mensaje de error. Si eso sucede, intente una recarga en caliente. (Presione el ícono Ejecutar cerca
de la parte superior de la ventana principal de Android Studio). ¿Y si falla la recarga en caliente? En ese caso,
presione el ícono Detener, el ícono cuadrado rojo que está en la misma fila que el ícono Ejecutar. Cuando
presiona el ícono Detener, la ejecución de su aplicación finaliza por completo. Presionar el ícono Ejecutar para
comenzar de nuevo puede solucionar el problema.

La Figura 3-12 muestra lo que obtiene cuando ejecuta el código del Listado 3-2.

FIGURA 3-12:
Sí, has
centrado el texto.

CAPÍTULO 3“Hola” de Flutter 85


Creando un andamio
losTextoEl widget de la figura 3-12 parece tan solitario. Agreguemos algo de fanfarria a la aplicación
básica. Listado 3-3 tiene el código; Las Figuras 3-13 y 3-14 le muestran la nueva pantalla.

LISTADO 3-3: usando un andamio

importar 'paquete: flutter/material.dart';

principal() => ejecutarAplicación(Aplicación0303());

clase App0303 extiende StatelessWidget {


Compilación del widget (contexto BuildContext) {
devolver MaterialApp(
hogar:Andamio(
barra de aplicaciones: barra de aplicaciones (

título: Texto ("Mi primer andamio"),


),
cuerpo: Centro(
niño: Texto("¡Hola mundo!"),
),
cajón: cajón (
niño: centro (
child: Text("Soy un cajón"),
),
),
),
);
}
}

FIGURA 3-13:
¡Mirad! A
¡andamio!

86 PARTE 2Aleteo: una vista de Burd's-Eye


FIGURA 3-14:
sacando un
cajón.

loshogarparaMaterialAppno tiene que ser unMaterialartilugio. En el Listado 3-3, el


hogares unAndamio.Cuando las empresas construyen rascacielos, crean andamios:
estructuras temporales de madera para apoyar a los trabajadores en lugares altos. En
programación, unandamioes una estructura que proporciona una funcionalidad básica y
de uso frecuente.

losAndamioconstructor en el Listado 3-3 tiene tres parámetros: unbarra de aplicaciones,a


cuerpo,y uncajón.En las Figuras 3-13 y 3-14, elbarra de aplicacioneses la región oscura en la parte
superior de la pantalla. loscuerpoes la gran región blanca que contiene elCentrocon suTextoartilugio.
En la Figura 3-14, el cajón es el área blanca grande que aparece cuando el usuario desliza el dedo
desde el borde izquierdo de la pantalla. El cajón también aparece cuando el usuario presiona el icono
de "hamburguesa": tres líneas horizontales cerca de la esquina superior izquierda de la pantalla.

loscuerpono es nada especial Es muy parecido a la pantalla completa en los ejemplos


anteriores. Pero elbarra de aplicacionesycajónson nuevos. losbarra de aplicacionesycajónson
dos de las cosas que puedes tener cuando creas unAndamio.Otras cosas puestas a disposición
porAndamiolos widgets incluyen barras de navegación, botones flotantes, hojas inferiores,
botones de pie de página y más.

En este capítulo, los Listados 3-1 y 3-2 tienenMaterialwidgets, y el Listado 3-3 tiene un
Andamio.Estos widgets forman los fondos de sus respectivas aplicaciones. Si quitas el
Materialwidget del Listado 3-1 o 3-2, la pantalla de su aplicación se convierte en un
desastre. Obtiene letras rojas grandes con subrayados amarillos sobre un fondo negro.
Lo mismo sucede cuando quitas elAndamiodel Listado 3-3. Existen otros widgets que
pueden proporcionar fondos para sus aplicaciones, peroMaterialyAndamioson los más
utilizados.

CAPÍTULO 3“Hola” de Flutter 87


Agregar ajustes visuales
Prueba este experimento: cambia elbarra de aplicacionesparámetro del Listado 3-3 al fragmento de
código en el Listado 3-4.

LISTADO 3-4: Un ligero cambio para el código del Listado 3-3

barra de aplicaciones: barra de aplicaciones (

título: Texto ("Mi primer andamio"),


elevación: 100,
brillo: Brillo.luz,
)

En la Figura 3-15, trato de mostrar el efecto de agregar elelevaciónybrillo


parámetros a labarra de aplicacionesllamada del constructor. Podría no tener éxito porque el efecto
de laelevaciónel parámetro es sutil.

FIGURA 3-15:
un ligero cambio
desde la pantalla
en la Figura 3-13.

En el lenguaje de diseño de materiales de Google, imagina que el fondo descansa sobre una
superficie plana y que otros componentes se elevan sobre el fondo en una cierta cantidad de
píxeles. Por unbarra de aplicaciones,la elevación predeterminada es 4, pero puede cambiar la
elevación de una barra con . . . espéralo . . laelevaciónparámetro.

La elevación de un componente afecta varios aspectos de la apariencia del componente.


Pero en esta sección, el cambio más obvio es probablemente la sombra debajo de la
Barra de aplicaciones.Es posible que no pueda ver la diferencia entre las sombras en las Figuras 3-13
y 3-15, pero cuando ejecuta el código en un dispositivo virtual o físico, aparece unbarra de
aplicacionesconelevación: 100proyecta una sombra bastante grande.

88 PARTE 2Aleteo: una vista de Burd's-Eye


Puede que te estés preguntando qué es lo que100enelevación: 100medio. ¿Son milímetros,
píxeles, puntos o años luz? En verdad, significa "100 píxeles independientes de la densidad", o
"100 dps", para abreviar. No importa qué pantalla tenga el usuario, un dp es 1/160 de pulgada.
Asi queelevación: 100significa 100/160 de pulgada (mejor conocido como cinco octavos de
pulgada).

Para conocer todos los detalles sobre la propiedad de elevación de Material Design, visitehttps://
material.io/design/environment/elevation.html.

Unbarra de aplicacioneswidgetsbrilloEl parámetro es otra cuestión. El efecto de agregar


brillo: Brillo.luzes decirle a Flutter que, debido a quebarra de aplicaciones
esluz,el texto y los iconos en la parte superior de labarra de aplicacionesdebería estar oscuro.
(Compare las Figuras 3-13 y 3-15). El texto oscuro y los íconos son fáciles de ver contra lo que se
considera una luz.Barra de aplicaciones.

Función de enumeración de Dart

Una característica interesante del lenguaje de programación Dart se esconde dentro del Listado
3-4. La palabraBrillose refiere a algo llamadoenumeración (pronunciado “ee-noom”). La
palabraenumeraciónes corto paraenumeración.Unenumeraciónes un montón de valores,
me gustaBrillo.luzyBrillo.oscuro.

En el Listado 3-4, observe cómo se refiere al valor de una enumeración. No usas una
llamada de constructor. En su lugar, utiliza el nombre de la enumeración (comoBrillo),
seguido de un punto, seguido de la parte única del nombre del valor (comoluzooscuro).

Flutter tiene muchas otras enumeraciones integradas. por ejemplo, elOrientaciónenumeración


tiene valoresOrientación.retratoyOrientación.paisaje.losEstado de animación
enumeración tiene valoresAnimationStatus.forward, AnimationStatus.reverse,
AnimationStatus.completed,yAnimationStatus.descartado.

Para averiguar cómo crear una nueva enumeración, consulte 7.

¡Hola desde la soleada California!


Google anunció Material Design en su conferencia de desarrolladores en 2014. La primera
versión de este lenguaje de diseño trataba principalmente con dispositivos Android, pero la
versión 2 adoptó marcas personalizadas para iPhone y otros dispositivos iOS. de aleteoMaterial
widget se ejecuta en iPhones con adaptaciones automáticas específicas de la plataforma.

Puede ejecutar cualquiera de este libroMaterialAppejemplos tanto en iPhone como en


teléfonos Android, pero si desea una estrategia de diseño centrada en el iPhone, puede usar la
colección de widgets Cupertino de Flutter. El listado 3-5 tiene un ejemplo.

CAPÍTULO 3“Hola” de Flutter 89


LISTADO 3-5: Cómo parecerse a una aplicación de iPhone

importar 'paquete: flutter/cupertino.dardo';

vacío principal() => ejecutarApp(App0305());

clase App0305 extiende StatelessWidget {


Compilación del widget (contexto BuildContext) {
devolverAplicación de Cupertino(

inicio: CupertinoPageScaffold(
barra de navegación: CupertinoNavigationBar(),
niño:Centro(
niño: Texto("¡Hola mundo!"),
),
),
);
}
}

El Listado 3-5 es muy parecido a su primo de Material Design, el Listado 3-3. Pero en lugar de
tenerMaterialApp, Andamioybarra de aplicacioneswidgets, el Listado 3-5 tiene la
CupertinoApp, CupertinoPageScaffold,yCupertinoNavegaciónBarwidgets
En lugar de importar 'paquete:flutter/material.dart',Listado de 3-5 importaciones
'paquete:flutter/cupertino.dart'. (Esteimportardeclaración hace que Flutter
La biblioteca de widgets de Cupertino está disponible para que la use el resto del código de la lista).

Los widgets Material Design y Cupertino de Flutter no son completamente paralelos entre sí.
por ejemplo, elAndamioLa llamada al constructor en el Listado 3-3 tiene uncuerpo
parámetro. En lugar de ese parámetro, elCupertinoPáginaAndamioLa llamada al constructor en el
Listado 3-5 tiene unniñoparámetro. En caso de duda, consulte las páginas de documentación oficiales
de Flutter para averiguar qué nombres de parámetros pertenecen a las llamadas del constructor de
los widgets.

Puede mezclar y combinar widgets de Material Design y Cupertino en la misma aplicación. Incluso
puede adaptar el estilo de diseño de su aplicación para diferentes tipos de teléfonos. Incluso puede
poner código del siguiente tipo en su aplicación:

si (Plataforma.isAndroid) {
// Hacer cosas específicas de Android

}
si (Plataforma.isIOS) {
// Hacer cosas específicas de iOS

Para más información visitehttps://pub.dev/packages/device_info.

90 PARTE 2Aleteo: una vista de Burd's-Eye


Agregar otro widget
Cuando se te acaben los temas de conversación, puedes preguntarles a las personas sobre sus
familias. A veces te enteras de hechos interesantes, otras veces escuchas listas de quejas y
otras veces tienes un monólogo largo y aburrido. De una forma u otra, llena cualquier silencio
incómodo.

Cuando se trata de entender las relaciones familiares, aprendo lentamente. Alguien me


habla de la suegra de la esposa de su primo segundo, y tengo que pausar la conversación
para dibujar un diagrama mental. De lo contrario, estoy simplemente confundido.

Mi propio árbol genealógico es bastante simple. Éramos mamá, papá y yo. La gente me
pregunta si me sentía solo siendo hijo único. "¡Diablos no!" Yo digo. “Como hijo único, no tenía
que compartir cosas”.

Esta discusión sobre familias es mi dudosa introducción al tema deColumna


widgets En los ejemplos anteriores, elTextowidget era hijo único. Pero finalmente, el
Textowidget debe aprender a compartir. (De lo contrario, elTextowidget se echa a
perder, como yo.)

¿Cómo pones a dos niños en el cuerpo de un andamio? Es posible que tengas la tentación de probar
esto:

// NO HAGAS ESTO:
cuerpo: Centro(
niño:Texto("¡Hola mundo!"),
niño:Otro Widget(...)
)

Pero una llamada de constructor no puede tener dos parámetros con el mismo nombre. ¿Entonces que
puedes hacer?

Flutter tiene unColumnaartilugio. losColumnael constructor del widget tiene unniños


parámetro. Los elementos secundarios del widget de columna se alinean, uno debajo del otro,
en la pantalla. ¡Eso suena prometedor! El listado 3-6 tiene algo de código y la figura 3-16 tiene la
pantalla resultante.

LISTADO 3-6: ¡Más widgets, por favor!

importar 'paquete: flutter/material.dart';

principal() => ejecutarAplicación(Aplicación0306());

clase App0306 extiende StatelessWidget {


(continuado)

CAPÍTULO 3“Hola” de Flutter 91


LISTADO 3-6: (continuado)

Compilación del widget (contexto BuildContext) {


devolver MaterialApp(
casa: Andamio(
barra de aplicaciones: barra de aplicaciones (

título: Texto ("Agregar widgets"),


),
cuerpo:Columna(
niños: [
Texto(
"¡Hola Mundo!",
factor de escala de texto: 2.0,

),
Texto ("Me siento solo dentro de este teléfono").
],
),
),
);
}
}

FIGURA 3-16:
me pregunto quien es
¡ahí!

AColumnaLa llamada al constructor tiene unniñosparámetro y elniñosel valor del parámetro


es una lista. En el lenguaje de programación Dart, unlistaes un montón de objetos. La posición
de cada objeto en la lista se denominaíndice. Los valores del índice comienzan desde 0 y
avanzan hacia arriba.

Una forma de crear una lista es encerrar los objetos entre corchetes. Por ejemplo, el
Listado 3-6 contiene una lista con dos objetos. (Vea la Figura 3-17.)

Los índices de una lista no comienzan con 1. Comienzan con 0.

92 PARTE 2Aleteo: una vista de Burd's-Eye


FIGURA 3-17:
Corchetes
crear listas de
cosas.

COSAS DE CUERDA
En el lenguaje de programación Dart, lo que rodeas con comillas (como en "¡Hola
Mundo!")se llama uncuerda. Es un montón de personajes, uno tras otro. Aquí hay
algunos datos útiles sobre las cadenas:

• Para crear una cadena, puede usar comillas dobles o comillas simples.

En otras palabras, '¡Hola Mundo!'es lo mismo que "¡Hola Mundo!".

• Es fácil poner una comilla simple dentro de una cadena entre comillas dobles.

Consulte la cadena

"Me siento solo dentro de este teléfono".

en el Listado 3-6.

• Es fácil poner comillas dobles dentro de una cadena entre comillas simples. Por

ejemplo, la siguiente es una cadena válida:

'"¡Ay!" ella dijo.'

• Uso de caracteres de barra invertida (\), puede colocar cualquier tipo de comillas dentro de
cualquier tipo de cadena.

Aquí hay dos ejemplos:

'Me siento solo dentro de este teléfono'. "\"¡Ay!\"


dijo ella."

(continuado)

CAPÍTULO 3“Hola” de Flutter 93


(continuado)

• Una cadena puede abarcar varias líneas si usa comillas triples.

Ambos ejemplos son código Dart válido:

'''Y el ganador es ...


¡Charles Van Doren!
"""Y el ganador es ...
¡Charles Van Doren!"""

• Para pegar cadenas una detrás de otra, use un signo más (+) o algunos espacios en blanco.

Ambos ejemplos son código Dart válido:

"Hola" + "mundo!"

"¡Hola Mundo!"

Para otras cosas que puede hacer con cadenas, consulte el Capítulo 4.

Centrar el texto (Parte 1)


La figura 3-16 se ve extraña porque las palabras están pegadas a la esquina superior izquierda.
En esta sección, lo guío a través de algunos pasos para diagnosticar este problema y
solucionarlo.

1.Mientras se ejecuta la aplicación en el Listado 3-6, busque en el borde derecho de la ventana de Android
Studio un botón de la barra de herramientas con las palabrasInspector de aleteo en eso. Haga clic en

ese botón de la barra de herramientas.

Como resultado, aparece Flutter Inspector. (Consulte la Figura 3-18.)

FIGURA 3-18:
el aleteo
Inspector.

2.En la esquina superior izquierda del Flutter Inspector, busque el icono Habilitar modo de
selección de widget. (Consulte la Figura 3-18.) Haga clic en ese icono.

3.Seleccione la pestaña Widgets de Flutter Inspector. (Una vez más, consulte la Figura 3-18.)

94 PARTE 2Aleteo: una vista de Burd's-Eye


4.En el árbol de widgets, seleccione Columna. (Consulte la Figura 3-19.)
Como resultado, el dispositivo que ejecuta su aplicación agrega resaltado y una
pequeña etiqueta alColumnawidget en la pantalla. (Vea la Figura 3-20.)

FIGURA 3-19:
Seleccionando un

rama de
el aleteo
El árbol del inspector.

FIGURA 3-20:
Seleccionar widget
el modo es realmente

¡útil!

5.Solo por diversión, seleccione algunas otras ramas en el árbol de widgets de Flutter
Inspector.

Puede determinar los límites de casi cualquiera de sus widgets utilizando esta
técnica.

El resaltado en la Figura 3-20 le dice que elColumnael widget no está centrado dentro de
su padreAndamiowidget, y no es lo suficientemente ancho para llenar todo el
Andamioartilugio. Para arreglar esto, ponga elColumnawidget dentro de unCentroartilugio.
Pon el cursor sobre la palabraColumnaen el editor de Android Studio y luego siga las
instrucciones al comienzo de la sección anterior "Hacer que las cosas se vean mejor". Listado
3-7 le muestra lo que obtiene.

CAPÍTULO 3“Hola” de Flutter 95


LISTADO 3-7: Centrar el widget de columna

importar 'paquete: flutter/material.dart';

principal() => ejecutarAplicación(Aplicación0307());

clase App0307 extiende StatelessWidget {


Compilación del widget (contexto BuildContext) {
devolver MaterialApp(
casa: Andamio(
barra de aplicaciones: barra de aplicaciones (

título: Texto ("Agregar widgets"),


),
cuerpo:Centro(
niño: Columna (
niños: [
Texto(
"¡Hola Mundo!",
factor de escala de texto: 2.0,
),
Texto ("Me siento solo dentro de este teléfono").
],
),
),
),
);
}
}

Cuando guarda los cambios, Android Studio realiza un reinicio en caliente y verá la
pantalla nueva y mejorada en la Figura 3-21.

FIGURA 3-21:
La columna
widget es
centrado.

96 PARTE 2Aleteo: una vista de Burd's-Eye


Centrar el texto (Parte 2)
losTextolos widgets en la Figura 3-21 están centrados horizontalmente, pero no están
centrados verticalmente. Para centrarlos verticalmente, puedes jugar con Flutter'sCentro
widget, pero hay una manera mucho más fácil.

1.En Flutter Inspector de Android Studio, seleccione elColumnaartilugio.


El panel inferior de Flutter Inspector muestra todas las propiedades de cualquier widget
que hayas seleccionado.

¡Esperar! ¿Qué es una “propiedad”? Todo objeto tienepropiedades, y cada propiedad de cada
objeto tiene unvalor. Por ejemplo, cada instancia de FlutterTextola clase tiene un
textScaleFactorpropiedad. En el Listado 3-7, una llamada al constructor establece unTexto
instanciastextScaleFactorpropiedad al valor 2.0.

Las llamadas a constructores no son la única forma de establecer las propiedades de los objetos.
En la Figura 3-22,El panel inferior del Flutter Inspector muestra los valores deColumna
widgetsdirecciónpropiedad, sualineación del eje principalpropiedad, y muchas otras
propiedades. Además, los dosTextolos niños aparecen en el panel inferior de Flutter
Inspector.

FIGURA 3-22:
Propiedades de la
columna (la
Widget de columna
eso esta construido
en el Listado 3-7).

CAPÍTULO 3“Hola” de Flutter 97


2.En el panel inferior, desplace el cursor sobre elColumnawidgetsalineación del eje principal
propiedad.

Cuando lo hace, Android Studio muestra una ventana emergente que explica elalineación del eje
principalsignificado de la propiedad. (Consulte la Figura 3-23). El texto de esta ventana
emergente proviene automáticamente de la documentación oficial de Flutter.

una columnaeje principales una línea invisible que va desde la parte superior de la columna hasta su parte

inferior.

FIGURA 3-23:
que es principal
alineación del eje,
¿de todos modos?

3.Nuevamente en el panel inferior, coloque el cursor sobre la palabracomienzoen elColumna


widgetsalineación del eje principalpropiedad.

La nueva ventana emergente dice que puede reemplazarcomienzocon cualquiera de los valoresfinal,
centro, espacio entre, espacio alrededor,oespacio uniformemente. (Consulte la Figura 3-24.)

FIGURA 3-24:
Los valores que tu
puede asignar a la
ejeprincipal
Alineación
propiedad.

4.En el editor de Android Studio, agregue unalineación del eje principalparámetro a la


Columnaconstructor de widgets. (Vea el Listado 3-8.)

98 PARTE 2Aleteo: una vista de Burd's-Eye


LISTADO 3-8: Tiempo para una alineación

importar 'paquete: flutter/material.dart';

principal() => ejecutarAplicación(Aplicación0308());

clase App0308 extiende StatelessWidget {


Compilación del widget (contexto BuildContext) {
devolver MaterialApp(
casa: Andamio(
barra de aplicaciones: barra de aplicaciones (

título: Texto ("Agregar widgets"),


),
cuerpo: Centro(
niño:
Columna(mainAxisAlignment:
MainAxisAlignment.center,niños: [
Texto(
"¡Hola Mundo!",
factor de escala de texto: 2.0,
),
Texto ("Me siento solo dentro de este teléfono").
],
),
),
),
);
}
}

En el Listado 3-8,alineación del eje principales el nombre de un parámetro,


Alineación del eje principales el nombre de una enumeración, yAlineación del eje principal.
centroes uno de los valores de la enumeración.

Para ver otra vez la función de enumeración de Dart, consulte la sección "Función de enumeración de

Dart" anteriormente en este capítulo. Y si anhelas aún más, consulta el Capítulo 7.

5.Guarde los cambios de su editor para hacer un reinicio en caliente.

En el dispositivo que está ejecutando su aplicación, elTextolos widgets están centrados


horizontal y verticalmente. (Vea la Figura 3-25.)

El ejemplo de esta sección ilustra aspectos de FlutterColumnawidget, que muestra las


cosas de arriba a abajo. No debería sorprender que Flutter tenga unFilawidget, que
muestra las cosas de lado a lado. La mayoría de los hechos sobre el
Columnawidget también son ciertas para elFilaartilugio. (Bueno, son ciertas cuando estás acostado
en lugar de sentado en posición vertical).

CAPÍTULO 3“Hola” de Flutter 99


FIGURA 3-25:
¡Que adorable!

Además, Flutter tiene unVista de la listaartilugio. losVista de la listawidget muestra las cosas
de cualquier manera: de arriba a abajo o de lado a lado. además, elVista de la lista
widget tiene su propia función de desplazamiento. Puedes poner 100 artículos en unVista de la listaa pesar de que

solo caben 20 elementos en la pantalla. Cuando el usuario se desplaza por la pantalla, los elementos se mueven fuera

de la pantalla mientras que otros elementos se mueven.

Para leer sobre FlutterVista de la listawidget, consulte el Capítulo 8.

Mostrar una imagen


Las palabras son bonitas, pero las imágenes son más bonitas. En esta sección, coloca una imagen en la pantalla de su

aplicación Flutter.

1.En Android Studio, inicia un nuevo proyecto de Flutter.


Nombré mi proyectoaplicación0308,pero no tienes que usar ese nombre.

2.En la ventana Project Tool de Android Studio, haga clic con el botón derecho en el nombre del proyecto.

Como resultado, aparece un menú contextual. (Vea la Figura 3-26.)

100 PARTE 2Aleteo: una vista de Burd's-Eye


FIGURA 3-26:
Haciendo clic derecho en el

sucursal app0308.

3.En el menú contextual, elija Nuevo-Directorio. (Consulte la Figura 3-26.)


Como resultado, aparece el cuadro de diálogo Nuevo directorio. ¡Que conveniente!

4.En el cuadro de diálogo, escriba el nombreactivos,y luego presione Entrar.


Para ser honesto, puedes nombrar este nuevo directorio casi como quieras. Pero si
no lo nombrasactivos,confundirás a otros desarrolladores de Flutter.

5.Compruebe la ventana de la Herramienta de proyecto para asegurarse de que el árbol del proyecto tiene un
nuevoactivosrama. (Consulte la Figura 3-27.)

Los desarrolladores experimentados de Flutter crean unimágenessubdirectorio de la nuevaactivos

directorio. No me molestaré con eso ahora.

FIGURA 3-27:
los activos
directorio es un
subdirectorio de
la aplicación0308
directorio.

6.Encuentra un archivo de imagen.

Busque en el disco duro de su computadora de desarrollo un archivo de imagen. Busque


nombres de archivo que terminen en .png, .jpg, .jpeg,o .gif.

Si su Explorador de archivos o Finder no muestra las extensiones de nombre de archivo (como .png, .
jpg, .jpeg,o .gifpara archivos de imagen), consulte la barra lateral en el Capítulo 2 que habla sobre esas
molestas extensiones de nombre de archivo.

7.En el Explorador de archivos o Finder de su computadora de desarrollo, copie el archivo de


imagen.

Es decir, haga clic derecho en el nombre del archivo de imagen. En el menú contextual que aparece,

seleccione Copiar.

8.Usando la ventana Project Tool de Android Studio, pegue el archivo de imagen en el


activosdirectorio.

Es decir, haga clic derecho en elactivosrama. En el menú contextual resultante, seleccione Pegar.
En el cuadro de diálogo resultante, escriba un nombre para su archivo de imagen y luego
presione Entrar.

CAPÍTULO 3“Hola” de Flutter 101


Cuando hice todo esto, nombré el archivoMiImagen.png,pero no tienes que usar ese
nombre.

9.Abre tu proyectopubspec.yamlexpediente.
Más específicamente, haga doble clic en elpubspec.yamlrama en el árbol de la ventana
Project Tool.

Aquí hay un hecho divertido: la extensión .Yamlsignifica Otro lenguaje de


marcado más.

10En elpubspec.yamlarchivo, busque consejos sobre cómo agregar activos a su


proyecto.

El consejo podría verse así:

# Para agregar activos a su aplicación,


# agregue una sección de activos, como esta:

# activos:
# - imágenes/a_dot_burr.jpeg
# - imágenes/a_dot_ham.jpeg

(En caso de que se lo pregunte, los nombres de los archivosa_dot_burr.jpegya_dot_ham. jpeg


referirse a Aaron Burr y Alexander Hamilton. Estos nombres de archivo aparecen muchas veces
en la documentación oficial de Flutter. Flutter es la tecnología detrás de la aplicación móvil para el
musical de Broadwayhamilton.)

En un .Yamlarchivo, un hashtag (#) le dice a la computadora que ignore todo el resto de la línea.
Entonces, en esta parte del .Yamlarchivo, ninguna de las líneas tiene ningún efecto.

11Elimina los hashtags en dos de las líneas. En la segunda línea, cambie el


nombre del archivo de imagen al nombre que eligió en el Paso 8.

Cuando hago esto, mipubspec.yamlarchivo contiene el siguiente texto:

# Para agregar activos a su aplicación,


# agregue una sección de activos, como esta:

activos:
- MiImagen.png

# - imágenes/a_dot_ham.jpeg

yo uso el nombreMiImagen.pngen vez deimágenes/MiImagen.pngporque, en el


Paso 5, no creé unimágenesdirectorio.

A menudo me olvido de hacer los cambios necesarios en elpubspec.yamlexpediente.


Trate de no olvidar este paso. Cuando lo olvide (y casi todos lo hacen), regrese y edite el
proyectopubspec.yamlexpediente.

102 PARTE 2Aleteo: una vista de Burd's-Eye


12Reemplace todo el código en eldardo principalarchivo con el código del Listado 3-9.
Use su propio nombre de clase y nombre de archivo en lugar de miaplicación0309yMi imagen.
pngnombres

LISTADO 3-9: Mostrar una imagen

importar 'paquete: flutter/material.dart';

principal() => ejecutarAplicación(Aplicación0309());

clase App0309 extiende StatelessWidget {


Compilación del widget (contexto BuildContext) {
devolver MaterialApp(
casa: Andamio(
barra de aplicaciones: barra de aplicaciones (

título: Texto ("Mi primera imagen"),


),
cuerpo: Centro(
hijo: Imagen.activo('MiImagen.png'),
),
),
);
}
}

13Deja que se rompa.

Es decir, ejecutar el código en un dispositivo virtual o físico. La visualización en la pantalla


del dispositivo se parece al resultado de la Figura 3-28.

En este punto, quiero dejar una cosa perfectamente clara: no soy narcisista. La razón por la que
utilizo la imagen de la portada de este libro en la figura 3-28 es que me fascina la recursividad.
Me gusta tener una referencia a este libro dentro de este libro.

(Además, soy un poco narcisista).

Flutter tiene unImagenclase, y laImagenLa clase tiene varios constructores diferentes. los
Imagen.activoconstructor en el Listado 3-9 toma un archivo de un lugar dentro del
directorio de su proyecto Flutter. Para obtener una imagen de Internet, llama a un
constructor diferente: elImagen.redconstructor. Para obtener una imagen de algún lugar
de su disco duro (en algún lugar fuera del directorio de su proyecto Flutter), puede llamar
alArchivo de imagenconstructor. Cada uno de estos constructores se llamaconstructor
nombrado. En cada caso, las cosas después del punto (.activo, .red,y .expediente)es ese
constructor en particularnombre.

CAPÍTULO 3“Hola” de Flutter 103


FIGURA 3-28:
Encontrar
Figura 3-28, mira
dentro de esoAleteo
Para Dummies
libro.

Oye, espera un minuto. . .


Este capítulo cubre algunas ideas fundamentales en el desarrollo de aplicaciones Dart y Flutter.
Comienza con un programa Hello World y realiza varios cambios en él. Mientras hace todo eso,
construye un vocabulario de conceptos útiles: conceptos como clases, constructores,
enumeraciones y widgets.

Has hecho todo eso mientras yo hábilmente desviaba tu atención de varias líneas en el
programa Hello World. ¿Qué hacen las primeras cuatro líneas del programa Hello World?
¿Por qué devuelves algo cuando construyes unMaterialApp?

Las respuestas a estas preguntas, y otras similares, se encuentran en el próximo capítulo. ¿Que
estas esperando? ¡Sigue leyendo!

♪“Felices caminos para ti / Hasta que nos volvamos a encontrar”♪

ESCRITO PORDALE EVANS, CANTADA POR ROY ROGERS Y DALE EVANS EN


“EL ESPECTÁCULO DE ROY ROGERS”, 1944–1957

104 PARTE 2Aleteo: una vista de Burd's-Eye


EN ESTE CAPÍTULO

»Mirando funciones en una aplicación Flutter

»Aprendiendo a escribir

»Tratar con variables y otros pequeños


cosas

Capítulo 4
Hola de nuevo
♪“Hola, hola de nuevo, sh-boom y espero que nos volvamos a encontrar”.♪
— JAMES KEYES, CLAUDE FEASTER, CARL FEASTER, FLOYD F. MCRAE Y
JAMES EDWARDS, CANTO POR LOS ACORDES, LOS CORTES DE EQUIPO,
STAN FREBERG Y OTROS, 1954

C El capítulo 3 se trata de un sencillo programa Hola mundo. Para mayor comodidad,


copio una versión del código aquí, en el Listado 4-1.

LISTADO 4-1: Otra mirada más al primer programa Hello

importar 'paquete: flutter/material.dart';

principal() => ejecutarAplicación(Aplicación0401());

clase App0401 extiende StatelessWidget {


Compilación del widget (contexto BuildContext) {
devolver MaterialApp(
casa: Material(
niño: Centro (niño: Texto ("¡Hola mundo!")),
),
);
}
}

CAPÍTULO 4Hola de nuevo 105


En el Capítulo 3, le pido que se concentre en la mitad del programa: el
MaterialAppy todo lo que hay dentro. Te dejo alegremente ignorar las otras partes del
programa. En particular, te dejo ignorar todo lo que tenga que ver con cosas llamadas
"funciones". Este capítulo continúa el recorrido de un programa Hello World y establece
sus sitios en esas cosas de "función".

Crear y usar una función


He aquí un experimento: ejecute la aplicación cuyo código se muestra en el Listado 4-2.

LISTADO 4-2: Palabras, palabras, palabras

importar 'paquete: flutter/material.dart';

principal() => ejecutarAplicación(Aplicación0402());

clase App0402 extiende StatelessWidget {


Compilación del widget (contexto BuildContext) {
devolver MaterialApp(
casa: Material(
niño: Centro (niño: Texto (resaltar ("Mírame"))),
),
);
}
}

resaltar (palabras) {
return "***" + palabras + "***";
}

Puede descargar el código de esta aplicación (y el código para cualquier otra lista en este
libro) de mi sitio web. la URL eshttps://allmycode.com/Flutter.

La Figura 4-1 le muestra el resultado de la aplicación en el Listado 4-2.

FIGURA 4-1:
Otro emocionante
Aplicación de aleteo.

El listado 4-2 contiene una declaración de función y una llamada de función. (Consulte la Figura 4-2.)

106 PARTE 2Aleteo: una vista de Burd's-Eye


FIGURA 4-2:
lo más destacado
función en
Listado 4-2.

La declaración de la función
Piense en una receta: un conjunto de instrucciones para preparar una comida en particular.
Una declaración de función es como una receta: es un conjunto de instrucciones para realizar
una tarea en particular. En el Listado 4-2, este conjunto de instrucciones dice: "Forma la cadena
que contiene asteriscos seguida de algunas palabras seguidas de más asteriscos y regresa esa
cadena a alguna parte".

La mayoría de las recetas tienen nombres, como Macaroni and Cheese o Triple Chocolate
Cake. La función al final del Listado 4-2 también tiene un nombre: Su nombre esdestacar.
(Vea la Figura 4-3.) No hay nada especial en el nombredestacar.inventé el nombre
destacartodo por mi cuenta

FIGURA 4-3:
un encabezado

y un cuerpo

CAPÍTULO 4Hola de nuevo 107


En la Figura 4-3, el nombre de la funcióndestacarestá en la parte de la declaración llamada
encabezamiento. Las instrucciones de la función (devuelve "***" + palabras + "***")están en
la parte de la declaración llamadacuerpo.

Una receta de macarrones con queso se encuentra en un libro o en una página web. La receta
no hace nada. Si nadie usa la receta, la receta permanece inactiva. Lo mismo ocurre con la
declaración de una función. La declaración del Listado 4-2 no hace nada por sí sola. La
declaración simplemente se sienta allí.

Una llamada de función

Eventualmente, alguien podría decir: “Por favor, haz macarrones con queso para la cena”,
y luego alguien sigue las instrucciones de la receta de macarrones con queso. De una
forma u otra, el proceso comienza cuando alguien dice (o tal vez solo piensa) el nombre
de la receta.

ALlamada de funciónes un código que dice: "Ejecute las instrucciones de una declaración
de función en particular". Imagine un teléfono u otro dispositivo que esté ejecutando el
código del Listado 4-2. Cuando el teléfono encuentra la llamada de funciónresaltar
("Mírame"),el teléfono se desvía de su tarea principal: la tarea de construir una aplicación
con suCentro de materiales,yTextowidgets El teléfono toma un desvío para ejecutar las
instrucciones en eldestacarcuerpo de la función. Después de darse cuenta de que
debería crear "***Mírame ***",el teléfono vuelve a su tarea principal, agregando el
Textowidget con "***Mírame ***"haciaCentrowidget, agregando elCentrowidget para
elMaterialartilugio, y así sucesivamente.

Una llamada de función consta del nombre de una función (como el nombredestacaren
el Listado 4-2), seguido de información de última hora (como "Mírame"
en el Listado 4-2).

¡Esperar! En la oración anterior, ¿qué significaalgo de informacion de ultima hora¿significar? sigue


leyendo

Parámetros y el valor de retorno


Suponga que su receta de macarrones con queso sirve a una persona y requiere dos
onzas de macarrones con coditos crudos. Has invitado a 100 personas a tu reunión
nocturna íntima. En ese caso, necesita 200 onzas de macarrones de codo crudos. En
cierto modo, la receta dice lo siguiente: “Para encontrar la cantidad de onzas de
macarrones con coditos crudos que necesita, multiplique la cantidad de porciones por 2”.
Ese número de porciones es información de última hora. La persona que escribió la
receta no sabe a cuántas personas atenderás. Usted proporciona un número

108 PARTE 2Aleteo: una vista de Burd's-Eye


de porciones cuando comience a preparar los macarrones con queso. Todo lo que dice la receta es
multiplicar ese número por 2.

De manera similar, eldestacarLa declaración de función en el Listado 4-2 dice: “Para


encontrar el valor que devuelve esta función, combine asteriscos seguidos por elpalabras
que desea que se resalte seguido de más asteriscos”.

La declaración de una función es como una caja negra. Le das algunos valores. La función
hace algo con esos valores para calcular un nuevo valor. Entonces la función devuelve ese
nuevo valor. (Consulte las Figuras 4-4 y 4-5.)

FIGURA 4-4:
Buenas cosas en,
buenas cosas.

FIGURA 4-5:
Adentro lo viejo,
afuera lo nuevo.

CAPÍTULO 4Hola de nuevo 109


Las figuras 4-4 y 4-5 muestran lo que significa dar valores a una función y que una
función devuelva un valor.

»Le das valores a una función con la lista de parámetros de la función.


Como cualquier llamada de constructor, cada llamada de función tiene una lista de parámetros.
Cada parámetro alimenta una pieza de información para que la función la use. En la Figura 4-5, la
llamada a la funciónresaltar ("Mírame")pasa el valor "Mírame"
haciadestacardeclaración de la función. Dentro de la declaración de la función,
el nombrepalabrasrepresenta "Mírame",entonces la expresión "***" +palabras
+ "***"representa "***Mírame ***".

»Devuelves un valor de una función con undevolverdeclaración.


En el Listado 4-2, la línea

return "***" + palabras + "***";

es undevolverdeclaración. De nuevo, imagine un teléfono que ejecuta el código del


Listado 4-2. Con la ejecución de estedevolverdeclaración, esto es lo que sucede:

• El teléfono deja de ejecutar cualquier código dentro del cuerpo deldestacar


función.

• El teléfono reemplaza toda la llamada de función con el valor devuelto para que

Centro (hijo: Texto (resaltar ("Mírame")))

efectivamente se convierte

Centro (hijo: Texto ("*** Mírame ***"))

• Continúa ejecutando cualquier código que estuviera ejecutando antes de que


la llamada a la función lo desviara. Continúa donde lo dejó, construyendo el
Centro, Material,yMaterialAppwidgets

Un libro de cocina puede tener solo una receta de fricasé de pollo, pero puedes seguir la receta
tantas veces como quieras. De la misma manera, una función en particular tiene solo una
declaración, pero una aplicación puede contener muchas llamadas a esa función. Para ver esto
en acción, mire el Listado 4-2 y cambie el códigoniñoparámetro, así:

niño: Columna (mainAxisAlignment: MainAxisAlignment.center, niños: [


Texto (resaltar ("Mírame")),
Text(highlight("Su atención, por favor"))
])

El nuevo hijo contiene dos llamadas aldestacarfunción, cada uno con su propio valor de
parámetro. La aplicación resultante es la que ve en la Figura 4-6.

110 PARTE 2Aleteo: una vista de Burd's-Eye


FIGURA 4-6:
Dos widgets de texto.

SALVANDO EL PLANETA
En el Capítulo 3, le aconsejo que termine cada lista de parámetros con una coma final. Es un buen consejo en la

mayoría de los casos. Pero, para los libros impresos, el número de páginas es muy importante. Para mantener este

libro en un tamaño razonable, he omitido algunas comas aquí y allá.

Por ejemplo, un extracto del código del Listado 4-2 se ve así:

casa: Material(
niño: Centro (niño: Texto (resaltar ("Mírame"))),
)

Cuando selecciona Código - Reformatear código, Android Studio formatea su código de acuerdo con las
pautas oficiales de Dart. (Dart usa una herramienta llamadadardofmt.) Cuando Android Studio formatea
el extracto del Listado 4-2, el extracto tiene solo tres líneas. La línea media termina con tres paréntesis
cerrados.

Pero, en lugar de tener tres paréntesis seguidos, puedo separar los paréntesis cercanos con
comas. Cuando hago eso, Android Studio formatea el código de esta manera:

casa: Material(
niño: centro (
niño: Texto(
resaltar ("Mírame"),
),
),
)

La herramienta Dartfmt interpreta una coma como una señal para iniciar una nueva línea de código. Esto duplica el

número de líneas en el extracto del código. ¡Me siento culpable por incluir tantas líneas en esta barra lateral!

Entonces, haz lo que digo, no lo que hago. Recuerde que muchos ejemplos en este libro omiten las comas

finales. Los ejemplos se ejecutan correctamente, pero el estilo del código está fuera de control. Agregue comas

al final para cumplir con las rigurosas pautas de Dart.

CAPÍTULO 4Hola de nuevo 111


Adevolverdeclaración es sólo uno de los varios tipos de declaraciones en el lenguaje de programación
Dart. Para obtener más información sobre este tema, consulte la sección “Declaraciones y
declaraciones”, más adelante en este capítulo.

En este capítulo, tengo cuidado de distinguir entre una declaración de función y una llamada de
función. En muchos otros capítulos, me vuelvo descuidado y me refiero a la declaración, al
llamamiento o a ambos como un simple y antiguofunción. No estoy solo en esta práctica. La mayoría
de los programadores hacen lo mismo.

Programación en Dart: Las cosas pequeñas


"Dart es aburrido". Eso es lo que dijo Faisal Abid durante una presentación en DevFest NYC
2017. No hablaba mal de Dart. Simplemente estaba explicando que Dart es muy parecido a
muchos otros lenguajes de programación. Si ha escrito algunos programas en Java, C++ o
JavaScript, encontrará que las funciones de Dart le son bastante familiares. Te encuentras con
algunas sorpresas, pero no demasiadas. Cuando estás aprendiendo a crear aplicaciones de
Flutter, no quieres que un lenguaje de programación nuevo y complicado se interponga en tu
camino. Entonces, un lenguaje aburrido como Dart es justo lo que necesitas.

Esta sección presenta algunos hechos poco interesantes sobre el lenguaje de programación Dart.
Intenta no quedarte dormido mientras lo lees.

Declaraciones y declaraciones
Adeclaraciónes un fragmento de código que ordena a Dart que haga algo. Si cree que esta
definición es vaga, está bien por ahora. De todos modos, en el Listado 4-2, la línea

return "***" + palabras + "***";

es una declaración porque ordena a Dart que devuelva un valor de la ejecución de la


destacarfunción.

A diferencia de una declaración, undeclaraciónpropósito principal es definir algo. por


ejemplo, eldestacardeclaración de función en el Listado 4-2 define lo que debería suceder
si y cuando eldestacarse llama la función.

Las sentencias y las declaraciones no están completamente separadas unas de otras. En


el Listado 4-2, eldestacarLa declaración de función contiene una declaración: una
devolverdeclaración. Una declaración de función puede contener varias sentencias. Por
ejemplo, la siguiente declaración contiene tres sentencias:

112 PARTE 2Aleteo: una vista de Burd's-Eye


resaltar2(palabras) {
print("¡Que sabes!");
print("¡Acabas de llamar a la función de resaltado2!");
return "***" + palabras + "***";
}

Las dos primeras sentencias (llamadas a Dart'simpresiónfunción) enviar texto a la ventana de la


herramienta Ejecutar de Android Studio. La tercera afirmación (ladevolverdeclaración) hace
resaltar ("Mírame")tener el valor "***Mírame ***".

Usa los dardosimpresiónfunciónsolamentepara probar tu código. Eliminar todas las llamadas aimpresión
antes de publicar una aplicación. Si no lo hace, podría enfrentar algunos problemas. En el mejor de los casos, las

llamadas no sirven para nada y pueden ralentizar la ejecución de su aplicación. En el peor de los casos, puede imprimir

datos confidenciales y mostrárselos a piratas informáticos malintencionados.

Función de escritura de Dart

¿Qué significa "cinco"? Puedes tener cinco hijos, pero también puedes medir un metro y
medio. Con cinco hijos, sabes exactamente cuántos hijos tienes. (A diferencia de la familia
estadounidense promedio, no puede tener 2,5 hijos). Pero si mide cinco pies de alto, es
posible que realmente mida cinco pies y media pulgada de alto. O podría medir cuatro
pies once y tres cuartos de pulgada y nadie discutiría al respecto.

¿Qué más puede significar “cinco”? Las plantas de energía nuclear pueden someterse a una evaluación de
vulnerabilidad inducida por incendios, también conocida comocinco. En este caso, “cinco” no tiene nada que
ver con un número. Son solo las cinco.

El significado de un valor depende del valorescribe.Considere tres de los tipos integrados


del lenguaje Dart:int, doble,yCuerda.

»UnEn tes un número entero, sin dígitos a la derecha del punto decimal.
Si tú escribes

En tcuántos niños = 5;

en un programa Dart, el5significa “exactamente cinco”.

»Adoblees un número fraccionario, con dígitos a la derecha del decimal


punto.

Si tú escribes

doblealtura = 5;

CAPÍTULO 4Hola de nuevo 113


en un programa Dart, el5significa "tan cerca de cinco como quieras medir".

»ACuerdaes un montón de personajes.


Si usa comillas simples (o comillas dobles) y escribe

Cuerdapulsación de tecla = '5';

en un programa Dart, el '5'significa “el carácter que parece una letra mayúsculaSpero
cuya mitad superior tiene vueltas puntiagudas.”

El tipo de un valor determina lo que puede hacer con ese valor. Considere los valores86
y "86".

»El primero,86, es un número. Puede agregarle otro número.


86 + 1es87

»El segundo,"86", es una cadena. No puede agregarle un número, pero


puede agregarle otra cadena.

"86" + "1"es "861"

En algunos idiomas, puede combinar cualquier valor con cualquier otro valor y producir algún
tipo de resultado. No puedes hacer eso en Dart. El lenguaje de programación Dart estipo
seguro.

Literales, variables y expresiones


El lenguaje Dart tiene literales y variables. el valor de unliterales el mismo en todos los
programas de Dart. Por ejemplo,1.5es literal porque1.5significa "uno y medio" en todos
los programas de Dart. Igualmente, "¡Hola Mundo!"en el Listado 4-1 es un literal porque "
¡Hola Mundo!"representa la misma cadena de 12 caracteres en todos los programas de
Dart. (Sí, el espacio en blanco cuenta como uno de los caracteres).

Dato curioso: en las primeras versiones de FORTRAN (alrededor de 1956), podías cambiar
el significado del literal5para que representara otra cosa, como el número 6. ¡Hablando
de confusión!

el valor de unvariableno es el mismo en todos los programas de Dart. De hecho, el valor de una
variable puede no ser el mismo de una parte de un programa Dart a otra. Tomemos, por
ejemplo, la siguiente línea de código:

int cuantos niños = 5;

114 PARTE 2Aleteo: una vista de Burd's-Eye


Esta línea se llamadeclaración de variables. La línea define una variable llamadacuantos
niñoscuyo tipo esEn t.La líneainicializaesa variable con el valor5. Cuando Dart encuentra
esta línea,cuantos niñosrepresenta el número 5.

Posteriormente, en el mismo programa, Dart puede ejecutar la siguiente línea:

cuantosniños = 6;

Esta línea se llamasentencia de asignación. la linea hacecuantos niñosconsulte 6 en lugar


de 5. ¡Felicitaciones por el nacimiento de un nuevo niño! ¿Es una niña o un niño?

Unexpresiónes una parte de un programa Dart que representa un valor. Imagine que su código
contiene las siguientes declaraciones de variables:

int numeroDeManzanas = 7;
int numeroDeNaranjas = 10;

Si comienza con estas dos declaraciones, cada entrada en la columna izquierda de la tabla 4-1
es una expresión.

TABLA 4-1 Expresiones fructíferas


Expresión Valor Escribe notas

7 7 En t

7.1 7.1 doble

7.0 7.0 doble Incluso con .0,obtienes undoble.

7.1 + 8 15.1 doble Adoblemás unEn tes undoble.

0,1 + 0,1 + 0,1 0.30000000000000004 doble aritmética endoblevalores no


siempre es exacto.

numerodemanzanas 7 En t

numerodenaranjas 10 En t

numeroDeManzanas + 17 En t ¿Quién dice que no puedes agregar


numerodenaranjas manzanas y naranjas?

8 + numeroDeManzanas 15 En t

númeroDeNaranjas * 10 100 Un asterisco (*) representa la


multiplicación.

(continuado)

CAPÍTULO 4Hola de nuevo 115


TABLA 4-1(continuado)

Expresión Valor Escribe notas

20 / 7 2.857142857142857 doble Una barra inclinada (/) realiza una división


y produce unadoble.

20.0 ~/ 7.0 2 En t La combinación ~/ realiza la


división y produce unaEn t.Eso
siempreredondea hacia abajo

(20 / 7).ronda() 3 En t Así es como se redondea hacia arriba o hacia


abajo al más cercanoEn tvalor.

20 % 7 6 En t Cuando divides 20 entre 7,


obtienes 2 con un resto de 6.

resaltar("Mira "*** Mírame ***" Cuerda Suponiendo que hayas declarado


yo") destacarcomo en el Listado 4-2, la
función devuelve unEstriar

'9' + númeroDeManzanas. '97' Cuerda numeroDeManzanas.toString()es


Encadenar() aCuerda.Su valor es '7'.

En la última fila de la Tabla 4-1, ¿realmente necesita elEncadenar()¿parte? Si tu puedes. Si


tú escribes '9' + número de manzanas,recibe un mensaje de error porque '9'es un
Cuerdaynumerodemanzanases un int. No puedes agregar unEn tvalor a unCuerda
valor.

El lenguaje Dart tiene declaraciones y expresiones. Adeclaraciónes una orden para hacer
algo; unexpresiónes un código que tiene un valor. Por ejemplo, la declaración
imprimir("Hola");hace algo. (MuestraHolaen la ventana de la herramienta Ejecutar de
Android Studio). La expresión3 + 7 * 21tiene un valor (Su valor es 150.)

Puedes aplicar Dart'sEncadenara cualquier expresión. Para ver algunos ejemplos, consulte el
Capítulo 7.

Dart proporciona una forma rápida de determinar el tipo de una expresión en particular. Para ver
esto, cambie eldestacardeclaración de función en el Listado 4-2 de la siguiente manera:

resaltar (palabras) {
imprimir (20 / 7);
imprimir((20 / 7).runtimeType);
return "***" + palabras + "***";
}

116 PARTE 2Aleteo: una vista de Burd's-Eye


Cuando ejecuta la aplicación, las siguientes líneas aparecen en la ventana de la herramienta Ejecutar de
Android Studio:

aleteo: 2.857142857142857
aleteo: doble

El valor de20 /7es2.857142857142857,y el valor de (20 / 7). tipo de tiempo de


ejecuciónesdoble.

Dos por el precio de uno


En Dart, algunas declaraciones cumplen una doble función como declaraciones y
expresiones. Como experimento, cambia eldestacaren el Listado 4-2 para que se vea así:

resaltar (palabras) {
int numeroDeKazoos;
print(numeroDeKazoos);
print(numeroDeKazoos = 94);
return "***" + palabras + "***";
}

Android Studio emite una advertencia de que elnumeroDeKazoosla variable no se usa, pero está
bien. Esto es solo un experimento. Esto es lo que ve en la ventana de la herramienta Ejecutar de
Android Studio cuando ejecuta este código:

aleteo: nulo
aleteo: 94

La líneaint numeroDeKazoos;es una declaración de variable sin una inicialización. Eso es


juego justo en el lenguaje de programación Dart.

Cuando Dart ejecutaprint(numeroDeKazoos);verásaleteo: nuloen la carrera


ventana de herramientas Mas o menos,nulono significa nada." En este punto del
programa, la variablenumeroDeKazoosha sido declarado pero aún no se le ha dado una
valor, entoncesnumeroDeKazooses todavíanulo.

Finalmente, cuando Dart ejecutaprint(numeroDeKazoos = 94);verásaleteo: 94


en la ventana de la herramienta Ejecutar. ¡Ajá! El códigonumeroDeKazoos = 94es tanto una afirmación como
una expresión! Este es el por qué:

»Como declaración,numeroDeKazoos = 94hace el valor denúmero de


kazoosser94.

»Como expresión, el valor denumeroDeKazoos = 94es94.

CAPÍTULO 4Hola de nuevo 117


De estos dos hechos, el segundo es más difícil de digerir para las personas. (He conocido a algunos
programadores experimentados que piensan en esto de manera incorrecta). Para ejecutar
print(numeroDeKazoos = 94);Dart sustituye encubiertamente94para la expresión
número de kazoos = 94,como se muestra en la Figura 4-7.

FIGURA 4-7:
lo mas interno de dart
pensamientos.

En otras palabras, el valornumeroDeKazoos = 94es94.Entonces, además de hacer


94también
algo, el códigonumeroDeKazoos = numeroDeKazoos = 94estiene
a la un valor. Es por eso
vez una afirmación y una expresión.

Las declaraciones de asignación simples no son las únicas cosas que funcionan como expresiones. Pruebe
este código para el tamaño:

numeroDeKazoos = 100;
print(numeroDeKazoos);
print(numeroDeKazoos++);
print(numeroDeKazoos);

La salida del código es

aleteo: 100
aleteo: 100
aleteo: 101

Si la línea media de salida te sorprende, no estás solo. Como declaración,


numeroDeKazoos++suma 1 al valor denúmero de kazoos,cambiando el valor de 100 a
101. Pero, como expresión, el valor denumeroDeKazoos++es 100, no 101. (Consulte la
Figura 4-7).

He aquí un pensamiento reconfortante. Para cuando Dart ejecuta el últimoimprimir


(númeroDeKazoos)declaración, el valor denumeroDeKazoosya ha cambiado a 101. ¡Uf!

118 PARTE 2Aleteo: una vista de Burd's-Eye


Como declaración, ++numeroDeKazoos (con los signos más delante) hace lo mismo que
numeroDeKazoos++hace: Suma 1 al valor denumeroDeKazoos.Pero, como expresión,
el valor de ++numeroDeKazoosno es lo mismo que el valor de
numeroDeKazoos++.Intentalo. Verás.

Dart tiene algunas otras declaraciones cuyos valores son expresiones. Por ejemplo, el
siguiente código imprimealeteo: 15dos veces:

int cuantasJirafas = 10;


print(cuantasjirafas += 5);
print(cuantasjirafas);

Y el siguiente código se imprimealeteo: 5000dos veces:

int conejoCuenta = 500;


imprimir(cuentaConejo *= 10);
imprimir(cuentaconejos);

Para obtener más información sobre temas como += y *=, visite esta página:

https://dart.dev/guides/language/language-tour#operators

Palabra clave var de Dart


En ocasiones, es posible que desee crear una variable cuyo tipo pueda cambiar. Para hacerlo,
declare la variable usando Dart'svariablepalabra clave y omitir una inicialización en la
declaración. Por ejemplo, el siguiente código no funcionará:

En tx = 7;
imprimir(x);

x = "Alguien está tratando de convertirme en un String";//no puedes hacer esto


imprimir(x);

Pero el siguiente código funciona bien:

variableX;

x = 7;
imprimir(x);

x = "Me he convertido en un String";//Dart está feliz de complacer


imprimir(x);

Otra razón para usarvariablees evitar nombres de tipo largos y complicados. Para ver un
ejemplo, consulte la sección "Tipos integrados" de este capítulo.

CAPÍTULO 4Hola de nuevo 119


HACEMOS UNA PAUSA PARA ALGUNOS COMENTARIOS

Es posible que haya notado algunas cosas que comienzan con dos barras inclinadas (//) en algunos de

los ejemplos de código del capítulo. Dos barras señalan el comienzo de un comentario.

Acomentarioes parte del texto de un programa. Pero a diferencia de las declaraciones, las llamadas al constructor y

otros elementos similares, el propósito de un comentario es ayudar a las personas a comprender su código. Un

comentario es parte de la documentación de un buen programa.

El lenguaje de programación Dart tiene tres tipos de comentarios:

• Comentarios al final de la línea

Uncomentario de fin de lineacomienza con dos barras inclinadas y va hasta el final de una línea de tipo.

Entonces, en el siguiente fragmento de código, el texto //Dart está feliz de complaceres un comentario de

final de línea:

x = "Me he convertido en un String";//Dart está feliz de complacer

Todo el texto en un comentario de final de línea es solo para ojos humanos. El compilador de
Dart no traduce la información de las dos barras al final de la línea.

• Bloquear comentarios

Abloquear comentariocomienza con /* y termina con */.

Un comentario de bloque puede abarcar varias líneas. Por ejemplo, el siguiente código es un
comentario de bloque:

/*Comentando temporalmente este código.


Es decir, omitiendo estas declaraciones para ver qué sucede: x =
"Alguien está tratando de convertirme en una Cadena"; imprimir(x);
*/

Una vez más, el compilador no traduce ninguna información entre /* y */.

• Comentarios del documento

Uncomentario de documento al final de la líneacomienza con tres barras (///). Abloquear comentario de

documento comienza con /** y termina con */.

Un comentario de documento está destinado a ser leído por personas que ni siquiera miran el código de

Dart. Pero eso no tiene sentido. ¿Cómo puedes ver un comentario de un documento si nunca miras el

código?

Bueno, cierto programa llamadodardodoc (¿qué más?) puede encontrar cualquier comentario de

documento en un programa y convertir estos comentarios en una página web atractiva. (Por un
ejemplo de una página de este tipo, visitehttps://api.flutter.dev/flutter/widgets/
Widget-class.html.)

120 PARTE 2Aleteo: una vista de Burd's-Eye


¿Qué es mejor: comentarios de documentos al final de la línea o comentarios de documentos en bloque? Los programadores

profesionales de Dart favorecen los comentarios de documentos al final de la línea sobre los comentarios de documentos en bloque.

Se burlan de los comentarios de documentos de bloque y de los comentarios de documentos de bloque. No ponen ningún stock en

los comentarios de documentos de bloque. No asimilan los comentarios de documentos de bloque. En su opinión, un comentario de

documento al final de la línea es excelente, pero la idea de un comentario de documento en bloque es una tontería.

Una idea más sobre los comentarios en general: en el Capítulo 3, describo una forma de mostrar las
etiquetas de cierre en el editor de Android Studio.

casa: Material(
niño: Texto("¡Hola mundo!"),
) , //Material

¿Eso final? //Material¿Te parece un comentario? Bueno, en realidad no es un comentario. (Lo


siento). Las etiquetas de cierre pertenecen a una categoría más amplia de artículos llamados
decoración de código. Cuando Android Studio crea una decoración de código, no agrega la
decoración al texto del programa. Solo muestra esa decoración en el editor. Si examina el texto de
un programa con el Bloc de notas o TextEdit, no verá la decoración del código.

Tipos incorporados

En un programa Dart, cada valor tiene unescribe.Dart tiene diez tipos integrados. (Consulte la
Tabla 4-2.)

TABLA 4-2 Tipos incorporados de Dart

Escribe un nombre Cómo se ven los literales Información útil sobre el tipo

Tipos de números

En t 42 Números sin dígitos a la derecha del punto decimal,


por lo general, de –9007199254740992 a
9007199254740991.

doble 42,0 42,1 Números con dígitos a la derecha del punto decimal
(posiblemente, todos cero dígitos).

número 42 42,0 42,1 Un número de algún tipo. CadaEn tvalor, y cada


doblevalor, es un ejemplo de unnúmerovalor.

(continuado)

CAPÍTULO 4Hola de nuevo 121


TABLA 4-2(continuado)

Escribe un nombre Cómo se ven los literales Información útil sobre el tipo

Tipos de colección

Lista [2, 4, –9, 25, 18] Un montón de valores. El valor inicial es el 0, el siguiente
valor es el 1, el siguiente valor es el 2 y así sucesivamente.
["Hola", "Adiós", 86] (Con [], el grupo no tiene valores).

[]
<int>[]

Establecer {2, 4, –9, 25, 18} Un montón de valores sin duplicados en ningún orden en
particular. (Con {}, el grupo no tiene valores).
{"Hola", "Adiós", 86}

{}
<int>{}

Mapa { 'uno': 1, 'dos': 2, Un montón de pares, cada par consiste en unllave(como


'uno dos tres',o 'muchos')y unvalor(como
'tres': 3, 'muchos': 99} 1, 2, 3,o99). (Con {}, el grupo no tiene pares).
<Cadena, entero>{}

Otros tipos

Cuerda 'Dardo es aburrido' Una secuencia de caracteres.

""
"""El anterior

la cadena está vacía."""

bool verdadero Falso Un valor lógico. Una variable de este tipo tiene uno de los dos
únicos valores posibles:verdaderoyfalso.

runas Runas('Yo ' '\u2665' 'tú') Una cadena de caracteres Unicode. Por ejemplo, '\u2665'
es un personaje de corazón (♥).

Símbolo (No aplica) Convierte un identificador en un programa Dart en un valor en un


programa Dart. (¡No te preocupes por eso!)

Puede combinar tipos para crear nuevos tipos. Una forma de hacer esto es poner tipos
dentro de tipos de colección. Por ejemplo, en la siguiente declaración, las cantidades
variables son unListaque contiene soloEn tvalores.

List<int> cantidades = [7, 3, 8, 2];

122 PARTE 2Aleteo: una vista de Burd's-Eye


Por supuesto, puedes volverte loco superponiendo tipos dentro de tipos dentro de otros tipos:

Mapa<Cadena, Mapa<Cadena, Lista<int>>>valores = {


"Tamaño": {

"Pequeño": [1, 2, 3],


},
};

En casos como ese, su mejor apuesta es usar elvariablepalabra clave. Por lo general, Dart
puede resolver las cosas mirando el resto del código.

variablevalores = {

"Tamaño": {

"Pequeño": [1, 2, 3],


},
};

Tipos que no están integrados


Además de los tipos de la tabla 4-2, cada clase es un tipo. Por ejemplo, en el Listado 4-1,
aplicación0401es el nombre de un tipo. Es un tipo que se define en el Listado 4-1. Puede
agregar una línea al Listado 4-1 que haga que una variable se refiera a una instancia del
aplicación0401clase. Aquí hay una de esas líneas:

App0401 miAplicación = App0401();

Como muchas otras declaraciones de variables, esta línea tiene un nombre de tipo (Aplicación0401),
seguido de un nuevo nombre de variable (mi aplicación),seguido de una inicialización. La
inicialización hacemiAplicaciónreferirse a una nueva construcciónaplicación0401instancia.

El lenguaje Dart viene con una biblioteca llena de código estándar reutilizable. El nombre
formal de tal biblioteca es unInterfaz de programación de aplicaciones(API). La API de Dart
tiene declaraciones de muchas clases. Por ejemplo, instancias de DartFecha y horaclase son
momentos en el tiempo, y las instancias de laDuraciónclase son intervalos de tiempo.

Del mismo modo, el kit de herramientas Flutter viene con una API rica en funciones. En el Listado 4-1,widget,

StatelessWidget, BuildContext, MaterialApp, Material, Center,yTextoson


los nombres de las clases en la API de Flutter.

Uso de declaraciones de importación

¡Ay de mí! no puedo leer el libroAleteo para tontosa menos que vaya a mi biblioteca local
y saque una copia. Lo mismo ocurre con las clases de biblioteca de Dart y Flutter.

CAPÍTULO 4Hola de nuevo 123


(bueno, casi). No puedes usar FlutterMaterialAppoMaterialclases a menos que comience
su programa con

importar 'paquete: flutter/material.dart';

Si eliminas esta línea, ni siquiera podrás usar ninguna de las funciones de Flutter.Widgetclases
(Sin estadoWidget, Widget, Centro,yTexto,para nombrar unos pocos). Eso es porque, cuando
importas 'paquete:flutter/material.dart',usted importa automáticamente
'paquete: aleteo/widgets.dart'además.

Un número relativamente pequeño de clases de API de Dart, como la mencionada anteriormenteFecha y hora

clase, pertenecen a un paquete llamadodardo.núcleo.Puede iniciar su programa con la


línea

importar 'dardo:núcleo';

pero no te hará ningún bien. clases de ladardo.coreel paquete siempre se importa, ya


sea que lo solicite o no.

Nadie (y quiero decirnadie) memoriza los nombres de todas las clases en las bibliotecas
Dart o Flutter. Cuando necesite saber acerca de una clase, búsquela visitando
https://api.flutter.dev.

Variaciones sobre un tema de


Die Flutter Mouse
Esta sección muestra algunas formas alternativas de crear declaraciones de funciones. El
listado 4-3 tiene el primer ejemplo.

LISTADO 4-3: Jugar con las declaraciones de funciones

importar 'paquete: flutter/material.dart';

principal() {

ejecutarAplicación(Aplicación0403());

clase App0403 extiende StatelessWidget {


Compilación del widget (contexto BuildContext) {
devolver MaterialApp(
casa: Material(

124 PARTE 2Aleteo: una vista de Burd's-Eye


niño: Centro (niño: Texto (resaltar ("Mírame"))),
),
);
}
}

resaltar(palabras) => "*** $palabras ***";

BRILLA TU CUERDA
El listado 4-2 contiene el siguiente código:

"***" + palabras + "***"

La yuxtaposición de signos más y comillas puede dificultar la lectura del código. Para facilitarle la
vida, Dart tiene interpolación de cadenas. Coninterpolación de cadenas, un signo de dólar ps
significa, "Ignore temporalmente las comillas que lo rodean y encuentre el valor de la siguiente
variable". Por eso, en el Listado 4-3, la expresión "*** $palabras ***"
representa "***Mírame ***" -la misma cadena que obtiene en el Listado 4-2.

¿No te impresiona la interpolación de cadenas? Mire la siguiente función y vea lo que


piensa de ella:

// La llamada a la función
obtenerInstrucciones1(8, "+", ";", "'")

// La declaración de la función
obtenerInstrucciones1(cuantos, char1, char2, char3) {
devolver "Contraseña:" +
cuantos.toString() +
" caracteres; No use " + char1 +

""+
char2 +
"o" +
char3;
}

Todo un lío, ¿no? El valor que elgetInstrucciones1la función devuelve es

Contraseña: 8 caracteres; No use +; o '

(continuado)

CAPÍTULO 4Hola de nuevo 125


(continuado)

Cada vez que intento escribir código de este tipo, olvido incluir algunos espacios en blanco, comillas u
otros elementos. Así es como obtiene el mismo valor de retorno usando la interpolación de cadenas:

// La llamada a la función
Texto(obtenerInstrucciones2(8, "+", ";", "'")

// La declaración de la función
obtenerInstrucciones2(cuantos, char1, char2, char3) {
return "Contraseña: $cuantos caracteres; No use $char1 $char2 o $char3";
}

Esta nueva función,obtenerInstrucciones2,es más fácil de crear y más fácil de entender


queobtenerInstrucciones1.

Cuando utiliza la interpolación de cadenas, puede ir un paso más allá. Esto es lo que puede
hacer cuando agrega llaves a la mezcla:

// La llamada a la función
obtenerInstrucciones3(8, "+", ";", "'")

// La declaración de la función
obtenerInstrucciones3(cuantos, char1, char2, char3) {
devolver "Contraseña:pscuantos + 1}caracteres; No use $char1 $char2 o
$char3";
}

este nuevogetInstrucciones3función devuelve

Clave:9caracteres; No use +; o '

La interpolación de cadenas puede manejar todo tipo de expresiones: expresiones aritméticas,


expresiones lógicas y otras.

Para leer todo sobre el signo de dólar ($) en la última línea del Listado 4-3, consulte la barra lateral
cercana "Bling your string".

Una ejecución del código del Listado 4-3 es la misma que la del Listado 4-2. (Consulte la Figura
4-1.) En cierto sentido, el Listado 4-3 contiene el mismo programa que el Listado 4-2. La
notación de las cosas es ligeramente diferente, pero las cosas mismas son las mismas.

En el Listado 4-3, eldestacardeclaración de función

resaltar(palabras) => "*** $palabras ***";

126 PARTE 2Aleteo: una vista de Burd's-Eye


es una abreviatura para el más prolijodestacardeclaración en el Listado 4-2. Cuando el
cuerpo de una declaración de función contiene solo una declaración, puede usar este
rápido y fácilflecha gorda(=>)notación.

En una declaración de función de flecha gruesa, nunca usa eldevolverpalabra clave.

Volviendo al Listado 4-2, utilizo la notación de flecha gruesa para declarar elprincipalfunción. Solo para
demostrar que puedo hacerlo, desactivo la flecha de esta declaración en el Listado 4-3.

Cada programa Dart tiene una función llamadaprincipal.Cuando comienza a ejecutar un


programa, Dart busca el programaprincipaldeclaración de la función y comienza a ejecutar las
declaraciones que se encuentran en el cuerpo de la declaración. En una aplicación Flutter, una
declaración como

ejecutarAplicación(Aplicación0403());

le dice a Dart que construya una instancia deaplicación0403y luego ejecute esa instancia. los
ejecutar la aplicaciónLa función es parte de la API de Flutter.

Escriba nombres en declaraciones de funciones


El Listado 4-4 agrega algunos nombres de tipo al código del Listado 4-2.

LISTADO 4-4: Más vale prevenir que lamentar

importar 'paquete: flutter/material.dart';

vacíoprincipal() => ejecutarAplicación(Aplicación0404());

clase App0404 extiende StatelessWidget {


Compilación del widget (contexto BuildContext) {
devolver MaterialApp(
casa: Material(
niño: Centro (niño: Texto (resaltar ("Mírame"))),
),
);
}
}

Cuerdadestacar(Cuerdapalabras) {
return "*** $palabras ***";
}

CAPÍTULO 4Hola de nuevo 127


En el Listado 4-4,Cuerdayvacíoagregue algo de redundancia bienvenida al código. La
ocurrencia deCuerdaen (palabras de cadena)le dice a Dart que, en cualquier llamada al
destacarfunción, lapalabrasel parámetro debe tener tipoCuerda.Armado con este extra
Cuerdainformación, Dart toserá y escupirá una mala llamada de función como

resaltar(19)

Esto es malo porque19es un número, no unCuerda.Puede discutir y decir: "Nunca


cometeré el error de poner un número en una llamada aldestacarfunción." Y mi
respuesta es: "Sí, lo harás, y yo también, y todos los demás programadores del mundo".
Cuando estás escribiendo código, los errores son inevitables. El truco es atraparlos más
temprano que tarde.

Cerca del final del Listado 4-4,Resaltado de cadenale dice a Dart que el valor devuelto por
eldestacarla función debe ser unaCuerda.Si accidentalmente escribe el siguiente código,
Dart se quejará como si no fuera asunto de nadie:

Cuerdaresaltar (palabras de cadena) {


devolver99; // ¡Código incorrecto!

Lo siento, jefe. El valor99no es unCuerda.

Continuando nuestro viaje a través del Listado 4-4,vacío principalno significa del todo, "La
principalla función debe devolver un valor de tipovacío."¿Por que no? Está bien poner un nombre de tipo
delante de una declaración de flecha ancha. Entonces, ¿qué tiene de diferente¿vacío principal?

Indicado simplemente,vacíono es un tipo. En cierto sentido,vacíosignifica “ningún tipo”. La palabravacío


le recuerda a Dart que estoprincipalSe supone que la función no devuelve nada útil. Intenta
declararvacío principaly poniendo undevolverdeclaración en el cuerpo de la declaración:

vacíoprincipal() {

ejecutarAplicación(Aplicación0404());

devolver 0; // Malo
}

Si hace esto, el editor de Android Studio agrega marcas rojas a su código. Dart está diciendo: “Lo
siento, Bud. No puedes hacer eso.

Nombrando sus parámetros


El Capítulo 3 distingue entre los parámetros posicionales de los constructores y los parámetros
con nombre. Todo ese alboroto sobre los tipos de parámetros se aplica a funciones como

128 PARTE 2Aleteo: una vista de Burd's-Eye


bien. Por ejemplo, la función de resaltado del Listado 4-4 tiene un parámetro: un
parámetro posicional.

resaltar ("Mírame") // Una llamada de función

Resaltar cadena (palabras de cadena) { // La declaración de la función


return "*** $palabras ***";
}

Si quieres, puedes girarpalabrasen un parámetro con nombre. Simplemente rodee el


parámetro con llaves:

destacar(palabras:"Mírame") // Una llamada de función

Resaltar cadena ({Palabras de cadena}) { // La declaración de la función


return "***" + palabras + "***";
}

Incluso puede tener una función con parámetros posicionales y con nombre. En la lista de
parámetros, todos los parámetros posicionales deben aparecer antes que cualquiera de los
parámetros nombrados. Por ejemplo, el siguiente código muestra +++¡Mírame! +++.

destacar( // Una llamada de función

"Mírame",
puntuación: "!",
símbolos: "+++",
)

Resaltar cadena ( // La declaración de la función


Cadena de palabras, {

puntuación de cadena,
símbolos de cadena,

}) {
volver símbolos + palabras + puntuación + símbolos;
}

¿Qué pasa con la función de compilación?


El Listado 4-4 contiene un código que parece familiar:

clase App0404 extiende StatelessWidget {


Compilación del widget (contexto BuildContext) {

devolver MaterialApp(

CAPÍTULO 4Hola de nuevo 129


Aquí hay algunos hechos:

»En este código,construires el nombre de una función, y


Compilación de widgets (contexto BuildContext)

es el encabezado de la declaración de la función.

losconstruirfunción hace exactamente lo que sugiere su nombre. Construye algo.


Para ser precisos, crea el widget cuyo contenido es toda la aplicación Flutter.

»losconstruirfunción devuelve un valor de tipoWidget.


Citando el Capítulo 3, "Ser una instancia de una clase puede convertirlo automáticamente en
una instancia de una clase más grande". De hecho, cada instancia de la
MaterialAppclase es automáticamente una instancia de laWidget con estadoclase,
que, a su vez, es automáticamente una instancia de laWidgetclase. Así que ahí lo
tienes, cadaMaterialAppes unWidget.Por eso está bien para elconstruir
funcionesdevolverdeclaración para devolver unMaterialAppobjeto.

»El único parámetro de la función tiene el tipoConstruirContexto.


Cuando Dart construye un widget, Dart crea unConstruirContextoobjeto y lo pasa al
widgetconstruirfunción. AConstruirContextoEl objeto contiene información sobre el
widget y la relación del widget con otros widgets en el programa. Para obtener más
información, consulte el Capítulo 6.

En el Listado 4-4, elconstruirla declaración de la función está dentro de laclase App0404


definición, pero ladestacarla declaración de la función no está dentroningúndefinición de clase.
En cierto sentido, estoconstruirfunción "pertenece a" instancias de laaplicación0404clase.

Una función que pertenece a una clase, oa las instancias de la clase, tiene un nombre especial.
se llama unmétodo. Más sobre esto en el Capítulo 5.

¡Más diversión por venir!

¿Qué sucede si un usuario toca la pantalla y quiere una respuesta de la aplicación en el


Listado 4-4? Absolutamente nada.

Arreglemos eso. Pase la página para ver lo que hay en el Capítulo 5.

♪“Adiós de nosotros a ti.”♪


— BÚFALO BOB EN “EL ESPECTÁCULO DE CÓMO DOODY”, 1947–1960

130 PARTE 2Aleteo: una vista de Burd's-Eye


EN ESTE CAPÍTULO

»¿Qué pasa cuando presionas


botones en la pantalla de un dispositivo

»La verdad sobre los estados de los widgets

»Cómo permanecer en el anonimato

»Cómo mover variables de una


lugar a otro

Capítulo5
Hacer que las cosas sucedan

T
l día es el 20 de octubre de 1952. En Kenia, el gobernador colonial británico declara
el estado de emergencia. En Filadelfia nace la actriz Melanie Mayron (nieta de
Frances Goodman). En los EE. UU., una entrega de "I Love Lucy" se convierte en el
primer episodio de televisión que se transmite más de una vez.

¿Qué? "Me encanta Lucy"? Sí, "Amo a Lucy". Hasta ese día no existían las reposiciones televisivas
(también conocidas como “repeticiones”). Todo en la televisión era nuevo.

Desde entonces, las transmisiones repetidas de programas de televisión se han convertido en la


norma. Gran parte del contenido de la televisión es una repetición de un video antiguo que las
emisoras ya no anuncian un "nuevo episodio". En cambio, anuncian la emisión de un “todo nuevo
episodio." La palabranuevoya no es lo suficientemente bueno. Los productos domésticos comunes no
son nuevos; son "nuevos y mejorados".

Por supuesto, promocionar cosas como "nuevas", "lo mejor" o "lo último" puede resultar
contraproducente. De hecho, la exageración de cualquier tipo puede resultar contraproducente.
Considere el caso de la crema de afeitar Swell de Stanley. En 1954, Stanley's era el líder del mercado.
Un año más tarde, cuando las ventas se estaban desacelerando, los anunciantes la rebautizaron como
Stanley's Neat New Shaving Cream. Al año siguiente, se convirtió en la Crema de Afeitar Superior de
Stanley. Las ventas del producto estuvieron bien durante los siguientes años. Pero a principios de la
década de 1960, las ventas se desplomaron y los anunciantes de Stanley estaban en un aprieto. ¿Qué
podría ser mejor que la "Crema de afeitar superior"? ¿Mejor que la mejor crema de afeitar? Después
de varias reuniones largas, un genio en el departamento de marketing ideó la crema de afeitar
Sensational Shocking Pink de Stanley, una mezcla de colores brillantes de jabón, glicerina, emolientes,
tinte rojo número 2 y probablemente algún pegamento de secado lento.

CAPÍTULO 5Hacer que las cosas sucedan 131


Ese fue el final de la línea. La idea de afeitarse con una crema de color rosa no era
popular entre los consumidores y la empresa de Stanley quebró. Los consumidores
hablaron de Stanley's Slimy Soap, Stanley's Ruby Rubbish y, lo peor de todo, Stanley's
Disgusting Dung.

Puede preguntar: "¿Qué demonios tiene que ver la crema de afeitar Stanley's con el desarrollo de
aplicaciones Flutter?" Mi punto es que existe el peligro de exagerar un producto, y exagerar un
concepto de desarrollo de aplicaciones no es mejor. En los Capítulos 3 y 4, uso términos elogiosos
para describir las estrategias de programación de Flutter, con sus constructores, funciones y otras
cosas buenas. Pero aquí, en el Capítulo 5, arrojé dudas sobre esos ejemplos introductorios porque
ninguno de ellos permite al usuario cambiar nada en la pantalla. Una aplicación que siempre muestra
el mismo texto anterior es aburrida y los usuarios calificarán la aplicación con cero estrellas. Una
aplicación interesante interactúa con el usuario. La pantalla de la aplicación cambia cuando el usuario
ingresa texto, toca un botón, mueve un control deslizante o hace algo más para obtener una
respuesta útil de la aplicación. Hacer que las cosas sucedan es esencial para cualquier tipo de
desarrollo de aplicaciones móviles. Entonces, en este capítulo, comienzas a aprender cómo hacer que
las cosas sucedan.

Presionemos todos un botón de acción flotante

Cuando creas un nuevo proyecto de Flutter, Android Studio hace undardo principalarchivo para usted. los
dardo principalEl archivo contiene una linda y pequeña aplicación de inicio. El Listado 5-1 tiene una versión
reducida de esa aplicación de inicio.

LISTADO 5-1: Presione un botón; Cambiar la pantalla

importar 'paquete: flutter/material.dart';

vacío principal() => ejecutarApp(App0501());

clase App0501 extiende StatelessWidget {


Compilación del widget (contexto BuildContext) {
devolver MaterialApp(
inicio: MiPáginaInicio(),
);
}
}

clase MyHomePage extiende StatefulWidget {


_MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extiende Estado {

132 PARTE 2Aleteo: una vista de Burd's-Eye


String _pressedOrNot = "No has pulsado el botón.";

void _cambiarTexto() {
setState(_getNewText);
}

void _getNewText() {
_pressedOrNot = "Ha presionado el botón.";
}

Compilación del widget (contexto BuildContext) {


andamio de vuelta(
cuerpo: Centro(
niño: Texto(
_presionado o no,
),
),
botón de acción flotante: botón de acción flotante (
onPressed: _cambiarTexto,
) );
}
}

El código del Listado 5-1 captura la esencia de la aplicación de inicio en la versión de octubre de
2019 de Android Studio. Para cuando lea este libro, es posible que los creadores de Flutter
hayan cambiado por completo la aplicación de inicio. Si las cosas del Listado 5-1 se parecen
poco a la aplicación de inicio que recibe cuando crea un nuevo proyecto, no se preocupe. Sólo
haz lo que has estado haciendo. Es decir, elimine todos los de Android Studiodardo principal
y reemplácelo con el código del Listado 5-1.

Cuando inicia la aplicación en el Listado 5-1, ve el texto "No ha presionado el botón" y, en


la esquina inferior derecha de la pantalla, un círculo azul. (Consulte la Figura 5-1.)

FIGURA 5-1:
Antes de presionar
el botón.

CAPÍTULO 5Hacer que las cosas sucedan 133


Ese círculo azul se llamabotón de acción flotante. Es uno de los widgets que puedes agregar a
unAndamio.Cuando hace clic en el botón de acción flotante de esta aplicación, las palabras en
la pantalla cambian a "Ha presionado el botón". (Consulte la Figura 5-2.)

FIGURA 5-2:
Después de presionar

el botón.

¡Al final! ¡Una aplicación Flutter está haciendo que algo suceda!

Para comprender lo que sucede, debe conocer dos tipos de widgets. Para aprender sus
nombres, lea el título de la siguiente sección.

Widgets sin estado y widgets con estado


Algunos sistemas tienen propiedades que pueden cambiar con el tiempo. Tomemos, por
ejemplo, su semáforo común y cotidiano. Si funciona correctamente, es rojo, amarillo o
verde. Imagina que tienes prisa por llegar al trabajo y te detienes en un semáforo en rojo.
En voz baja, puede quejarse: “Me molesta que el estado de este semáforo esté en rojo.
Deseo que el estado de ese sistema cambie a verde”. un sistema estadoes una propiedad
del sistema que puede cambiar con el tiempo.

Este consejo no tiene nada que ver con Flutter. Si te encuentras con alguien de otro país,
pregúntale el color de la bombilla del medio en un semáforo. Durante una breve conversación
con cinco personas, obtuve amarillo, ámbar, dorado y naranja. Vea cuántos nombres de colores
diferentes puede recolectar.

La aplicación del Listado 5-1 tiene una página de inicio (llamadaMi página de inicio),y esa página de
inicio está en uno de dos estados. Un estado se muestra en la Figura 5-1. Es el estado en el que el
Textowidget muestra "No ha presionado el botón". El otro estado se muestra en la Figura
5-2. Es el estado en el que elTextoel widget muestra "Has presionado el botón".

En el Listado 5-1, la primera línea de laMi página de iniciodeclaración de clase es

clase MyHomePage extiende StatefulWidget

134 PARTE 2Aleteo: una vista de Burd's-Eye


¿Quieres el aspecto de laMi página de iniciowidget para poder cambiarse a sí mismo ágilmente, por
lo que declaraMi página de inicioobjetos para serwidgets con estado. CadaMi página de inicio
instancia tiene un estado, algo sobre él que puede cambiar con el tiempo.

Por el contrario, elaplicación0501clase en el Listado 5-1 es unawidget sin estado. La aplicación en sí


(Aplicación0501)se basa en su página de inicio para realizar un seguimiento de cualquier texto que se
muestra. Por lo tanto, la aplicación no necesita recordar si está en un estado u otro. nada sobre un
aplicación0501cambios de instancia durante la ejecución de este código.

Piense de nuevo en un semáforo. La parte con las bombillas se apoya en un poste que se
sujeta de forma permanente al suelo. Todo el conjunto (poste, bombillas y todo) no
cambia. Pero las corrientes que pasan por las bombillas cambian cada 30 segundos más
o menos. Ahí tienes. Todo el ensamblaje no cambia y no tiene estado, pero una parte de
ese ensamblaje, la parte responsable de mostrar los colores, cambia y tiene estado.
(Consulte la Figura 5-3.)

FIGURA 5-3:
Un acertijo: ¿Cómo es un
programa de aleteo
como un semáforo?

Los widgets tienen métodos


En el Listado 5-1, la declaración de laaplicación0501clase contiene una función llamada
construir.Una función que se define dentro de una declaración de clase se llamamétodo. los
aplicación0501la clase tiene unconstruirmétodo. Eso es bueno porque hay una letra pequeña
en el código paraWidget sin estado.De acuerdo con esa letra pequeña, cada clase que se
extiendeWidget sin estadodebe contener la declaración deconstruirmétodo.

Un widget sin estadoconstruirEl método le dice a Flutter cómo construir el widget. Entre otras
cosas, el método describe el aspecto y el comportamiento del widget. Cada vez que inicia el
programa en el Listado 5-1, Flutter llama alaplicación0501de claseconstruirmétodo.

CAPÍTULO 5Hacer que las cosas sucedan 135


Queconstruirmétodo construye unMaterialAppinstancia, que, a su vez, construye unaMi
página de inicioinstancia. Y así. A partir de ese momento, elMaterialApp
la instancia no cambia. Sí, cosas dentro delMaterialAppcambio de instancia, pero la
instancia en sí no cambia.

¿Con qué frecuencia su ciudad construye un nuevo conjunto de semáforos? Donde vivo, puedo
ver uno subiendo cada dos años más o menos. La parte metálica de un semáforo no está
diseñada para cambiar regularmente. Los urbanistas convocan a la asamblea del semáforo
construirmétodo sólo cuando construyen una nueva luz. Lo mismo ocurre con los widgets sin
estado en Flutter. Un widget sin estado no está diseñado para cambiarse. Cuando un widget sin
estado requiere cambios, Flutter reemplaza el widget.

¿Qué pasa con los widgets con estado? Tienen ellosconstruir¿métodos? Bueno, lo hacen y no lo
hacen. Cada widget con estado debe tener uncrear estadométodo. loscrear estado
método crea una instancia de FlutterEstadoclase, y cadaEstadola clase tiene lo suyoconstruir
método. En otras palabras, un widget con estado no se crea solo. En cambio, un widget con
estado crea un estado y el estado se crea a sí mismo. (Consulte la Figura 5-4.)

FIGURA 5-4:
Widgets con estado
no fueron construidos

en un día.

136 PARTE 2Aleteo: una vista de Burd's-Eye


"ESTOY HABLANDO CONTIGO,
ARTÍCULO SIN ESTADO: DEBES TENER
¡UN MÉTODO DE CONSTRUCCIÓN!”

Cada clase que se extiendeWidget sin estadodebe tener unconstruirmétodo. La API de Flutter hace
cumplir esa regla.

Pero no confíes en mi palabra. Comentar temporalmente elconstruirdeclaración de método en el


Listado 5-1. Es decir, cambiar la declaración deaplicación0501para que quede así:

clase App0501 extiende StatelessWidget { //


Compilación del widget (contexto BuildContext) {
// devolver MaterialApp(
// inicio: MiPáginaInicio(),
// );
// }
}

Cuando lo haga, verá algunas marcas rojas en el editor de Android Studio. Las marcas rojas
indican que el programa contiene un error; a saber, queaplicación0501no tiene propio
construirmétodo.

Para comentar rápidamente varias líneas de código, arrastre el mouse para que el resaltado toque
cada una de esas líneas. Luego, si está usando Windows, presione Ctrl-/. Si está usando una Mac,
presione Cmd-/.

¿Cómo aplica Dart suconstruirrequisito de método? Como desarrollador novato, no es necesario que sepa
la respuesta. Puede omitir el resto de esta barra lateral y seguir felizmente su camino. Pero si tienes
curiosidad y no te importa tomar un pequeño desvío en tu aprendizaje, prueba esto:

En el editor de Android Studio, haga clic derecho en la palabraWidget sin estado.En el menú
contextual resultante, seleccione Ir a - Declaración.Et voila!Una nueva pestaña que contiene la
Widget sin estadodeclaración de clase se abre en el editor. Si ignora la mayor parte
del código en elWidget sin estadodeclaración de clase, verá algo como esto:

resumenclass StatelessWidget extiende Widget {


// Un montón de código del que no tienes que preocuparte, seguido de...

Compilación de widgets (contexto BuildContext);

(continuado)

CAPÍTULO 5Hacer que las cosas sucedan 137


(continuado)

la primera palabra,resumen,advierte a Dart que esta declaración de clase contiene métodos (es
decir, funciones) sin cuerpos. Y, de hecho, la línea

Compilación de widgets (contexto BuildContext);

es un encabezado de método sin cuerpo. En lugar de un cuerpo, solo hay un punto y coma.

Puede que no te sorprenda saber queWidget sin estadoes un ejemplo de un clase


abstractay que la claseconstruirmétodo es unmétodo abstracto. Con eso en mente,
te ofrezco estos dos hechos:

• No puede hacer una llamada de constructor para una clase abstracta.

Puedes construir unTextowidget escribiendoTexto("Hola")porque elTexto


la clase no es abstracta. Pero no puedes construir unWidget sin estadoescribiendo
Widget sin estado ().Eso tiene sentido porque, en la declaración de
Widget sin estado,laconstruirEl método no está completamente definido.

• Si extiende una clase abstracta, debe proporcionar una declaración completa para cada uno de
los métodos abstractos de la clase.

losWidget sin estadodeclaración de clase contiene la siguiente línea:

Compilación de widgets (contexto BuildContext);

Debido a esto, elaplicación0501clase en el Listado 5-1 debe contener un completoconstruir


declaración de método. Además, la declaración debe especificar un parámetro de tipo
ConstruirContexto.Efectivamente, elconstruirmétodo perteneciente aaplicación0501hace el
trabajo:

Compilación de widgets (contexto BuildContext){

devolver MaterialApp(
inicio: MiPáginaInicio(),
);
}

Con una definición completaconstruirmétodo, elaplicación0501la clase no es abstracta. Eso es bueno

porque, cerca de la parte superior del Listado 5-1, hay una línea que contiene unaplicación0501()llamada

del constructor.

El estado de un semáforo típico cambia cada 30 segundos o cada pocos minutos y, por lo tanto,
se reconstruye el estado de la luz. De la misma manera, elconstruirEl método que pertenece
(indirectamente) a un widget con estado se llama una y otra vez durante la ejecución de un
programa. Para eso están los widgets con estado. Son cosas ágiles cuya apariencia puede
cambiar fácilmente. Por el contrario, un widget sin estado es como el poste de un semáforo. Es
una estructura rígida pensada para un solo uso.

138 PARTE 2Aleteo: una vista de Burd's-Eye


No prestes atención al marco detrás
de la cortina.
Un programa que muestra botones y otras cosas bonitas tiene uninterfaz gráfica del usuario. Esta interfaz se
denomina comúnmente interfazinterfaz gráfica de usuario(pronunciado "pegajoso", como en "Esta
mantequilla de maní es realmente pegajosa"). En muchos programas GUI, las cosas suceden entre bastidores.
Mientras se ejecuta el código de su aplicación, muchos otros códigos se ejecutan en segundo plano. Cuando
ejecuta una aplicación Flutter, el código escrito por los creadores de Flutter se ejecuta constantemente para
admitir el código de su propia aplicación. Este código de soporte en segundo plano pertenece a laMarco de
aleteo.

El listado 5-1 tiene declaraciones para funciones nombradasprincipal, compilar, crear estado,
_getNewText,y _cambiar el texto,pero el código del Listado 5-1 no llama a ninguna de estas
funciones. En cambio, el código de marco de Flutter llama a estas funciones cuando un dispositivo
ejecuta la aplicación.

Aquí hay una descripción paso a paso:

»El lenguaje Dart llama alprincipalfuncionan cuando el código del Listado 5-1
empieza a correr

losprincipalfunción construye una instancia deaplicación0501y llamadasejecutar la aplicaciónpara hacer que las

cosas funcionen. Después . . .

»El framework Flutter llama alaplicación0501instanciasconstruirfunción.


losconstruirfunción construye una instancia deMi página de inicio.Después . . .

»El framework Flutter llama alMi página de inicioinstanciascrear estado


función.

loscrear estadola función construye una instancia de _myHomePageState.Después . . .

»El framework Flutter llama al_myHomePageStateinstanciasconstruir


función.

losconstruirfunción construye unAndamioque contiene unCentrocon unTexto


artilugio y unBotón de acción flotanteartilugio.

para entender elTextoconstructor del widget, mira algunas líneas de código:

String _pressedOrNot = "No has pulsado el botón.";

// Más adelante en el listado...

niño: Texto(
_presionado o no,
),

CAPÍTULO 5Hacer que las cosas sucedan 139


Inicialmente, el valor de _presionado o novariable es "No has presionado el
botón."Entonces, cuando la aplicación comienza a ejecutarse, elTextowidget muestra
obedientemente "No ha presionado el botón".

Pero el código del botón de acción flotante es una historia diferente.

void _cambiarTexto() {
setState(_getNewText);
}

void _getNewText() {
_pressedOrNot = "Ha presionado el botón.";
}

// Más adelante en el listado...

botón de acción flotante: botón de acción flotante (


onPressed: _cambiarTexto,
)

El constructor de laBotón de acción flotantetiene unonPressedparámetro, y el valor de


ese parámetro es _cambiarTexto.¿De que va todo eso?

losonPressedEl parámetro le dice a Flutter "Si y cuando el usuario presiona el botón, haga que
el dispositivo llame al _cambiarTextofunción." De hecho, suceden muchas cosas cuando el
usuario presiona el botón de acción flotante. En las próximas secciones, verá algunos de los
detalles.

el gran evento
En la programación GUI, uneventoes algo que sucede, algo que puede requerir una respuesta
de algún tipo. La pulsación de un botón es un ejemplo de un evento. Otros ejemplos de eventos
incluyen una llamada telefónica entrante, el movimiento de un dispositivo a una nueva
ubicación de GPS o el hecho de que una aplicación necesita información de otra aplicación.

Uncontrolador de eventoses una función que se llama cuando ocurre un evento. En el Listado
5-1, el _cambiarTextofunción es un controlador para el botónonPressedevento. En sí mismo,
el códigoonPressed: _changeTextno llama al _cambiarTextofunción. En cambio, ese código
registra la función_cambiarTextocomo controlador oficial de pulsaciones de botones de acción
flotante.

Una llamada a la _cambiarTextola función se vería así: _cambiarTexto().La llamada


terminaría con paréntesis de apertura y cierre. El códigoonPressed: _cambiarTexto, sin
paréntesis, no llama al _cambiarTextofunción. Ese código le dice al dispositivo que
recuerde que el nombre del botónonPressedcontrolador de eventos

140 PARTE 2Aleteo: una vista de Burd's-Eye


es _cambiarTexto.El dispositivo utiliza esta información cuando, y solo cuando, el usuario
presiona el botón.

Llámame
Un teléfono suena cuatro veces. Nadie responde, pero escucho un anuncio grabado.

“Este es Steve Hayes, editor ejecutivo de John Wiley and Sons. Siento no estar aquí para
atender tu llamada. Deje un mensaje y me pondré en contacto con usted tan pronto como
pueda”.<pitido>

"Hola Steve. Este es Barry. losAleteo para tontosEl manuscrito va muy bien, pero va a
tardar varios meses. Por favor llámeme para que podamos discutir un nuevo horario.
No me llames a mi número de teléfono habitual. En cambio, llámame a mi hotel en
Taha'a, Polinesia Francesa. El número es +689 49 55 55 55. ¡Adiós!”

Mi número de teléfono en Taha'a es un número de devolución de llamada. De la misma manera, las funciones

_cambiarTextoy _obtenerNuevoTextoen el Listado 5-1 sondevoluciones de llamada. La línea

onPressed: _changeText

le dice al marco: "Llámame llamando a mi _cambiarTextofunción." y la línea

setState(_getNewText)

le dice al marco "Llámame llamando a mi _obtenerNuevoTextofunción."

Las devoluciones de llamada son útiles

Es posible que haya escrito programas que no tienen devoluciones de llamada. Cuando su
programa comienza a ejecutarse, el sistema ejecuta la primera línea de código y sigue
ejecutando instrucciones hasta que llega a la última línea de código. Todo funciona según lo
planeado de principio a fin. (Bueno, en el mejor de los casos, todo sale según lo planeado).

Una devolución de llamada agrega un elemento de incertidumbre a un programa. ¿Cuándo tendrá lugar un
evento? ¿Cuándo se llamará a una función? ¿Dónde está el código que llama a la función? Los programas con
devoluciones de llamada son más difíciles de entender que los programas sin devoluciones de llamada.

¿Por qué necesita devoluciones de llamada? ¿Puedes escaparte sin tenerlos? Para ayudar a
responder a esta pregunta, piense en su despertador común y cotidiano. Antes de irte a dormir,
le dices al despertador que envíe un sonido a tus oídos (una devolución de llamada) cuando las
9SOYsucede el evento:

a las 9 a.m.: _rattleMyEarDrums,

CAPÍTULO 5Hacer que las cosas sucedan 141


Si no confiara en una devolución de llamada, tendría que realizar un seguimiento de la hora
toda la noche por su cuenta. Al igual que Bart y Lisa Simpson en el asiento trasero de un
automóvil, preguntará repetidamente: "¿Son las 9SOY¿aún? es 9SOY¿aún? es 9SOY¿aún?"
Ciertamente no podrías dormir bien por la noche. De la misma manera, si un programa de
Flutter tuviera que verificar cada cien milisegundos si se presionó un botón recientemente, no
habría mucho tiempo para que el programa hiciera algo más. Es por eso que necesita
devoluciones de llamada en los programas de Flutter.

La programación con devoluciones de llamada se llamaprogramación dirigida por eventos. Si un


programa no utiliza devoluciones de llamada y, en cambio, verifica repetidamente si se presionan
botones y otras cosas similares, ese programa esvotación. En algunas situaciones, el sondeo es
inevitable. Pero cuando la programación impulsada por eventos es posible, es muy superior al sondeo.

El esquema del código


Una buena manera de mirar el código es entrecerrar los ojos para que la mayor parte sea borrosa e
ilegible. La parte que aún puedes leer es la parte importante. La Figura 5-5 contiene mi versión
mayormente borrosa de algún código en el Listado 5-1.

FIGURA 5-5:
Qué buscar
en el Listado 5-1.

De acuerdo con la Figura 5-5, esta es la estrategia de gestión estatal del Listado 5-1:

1.Registro _cambiarTextocomo una función de devolución de llamada y espere a que el usuario presione el
botón de acción flotante.

Cuando, por fin, el usuario presiona el botón de acción flotante, . . .

142 PARTE 2Aleteo: una vista de Burd's-Eye

También podría gustarte