El widgetColumn, como ya vimos, nos permite organizar distintos elementos visuales de la interfaz (también widgets) de manera vertical, alineados uno arriba / debajo del otro en el eje Y.
Los widgets hijos, que van a ser organizados dentro de un Column padre, deben estar definidos en la propiedad children de éste, como un arreglo de elementos de tipo <Widget>[...].
Algo que debemos recordar es que los widgets que usamos como children, pueden definirse bien sea directamente (inline) o bien a través de clases externas (o widgets personalizados) que hemos definido previamente en archivos .dart independientes.
Para utilizar valores que nos permitan tener contenido dinámico en nuestra interfaz es necesario apoyarnos en el método constructor que lleva el mismo nombre de la clase y en el que definimos los parámetros de entrada que serán utilizados en lugar de las variables por defecto que también hemos definido antes.
Decidí hacer que la valoración de estrellas fuera más dinámica según la puntuación dada.
No estoy a la altura de entender lo que hiciste.
Ojalá algún día llegue a pescar algo de eso!
Me pareció genial el siguiente fragmento de código, desde la clase anterior estuve pensando como se podría llevar a cabo la validación para decidir que tipo de estrella asignar:
withBorder ?Icons.star:Icons.star_border
Sería interesante declarar la variable stars como double para poder incorporar estrellas con relleno a la mitad y generar otro operador para realizar la validación de los 3 tipos de estrellas.
Me gustó el código.
me tome el tiempo de comentar todo el codigo aqui el icono que escogi fue el favorite
import'package:flutter/material.dart';//Nos habilita los witgets los elementos que estaremos trabajando en esta interface//classDescripcionLugarextendsStatelessWidget{//class: crea una clase, extends: heredar, //StatelessWidget(widget sin estado: seran aquellos que se heredan de la clase StatelessWidget. son elementos fijos que no interactuan con el usuario ejemplo: icono, texto, contenedor con color ) @override
Widgetbuild(BuildContext context){//metodo build:es el metodo que construye la interface, construye el widget con los elementos que estaremos trabajando final estrella_sincolor =Container(//Container:tendra la estrella y le pondremos margenes para acomodar la estrella sin color en este casomargin:EdgeInsets.only(// EdgeInsets.only(), esto me permite generar un margen mas especifico a nivel de top, left, right, bottom//margin: margenes de nuestros elementos del containertop:349.0,//arribaright:3.0,//derecha),child:Icon(//child toma un solo widget toma un solo elemnto, en este caso toma el icono "estrella"Icons.favorite_border,//widget icono estrella con color a los bordescolor:Color(0xFFF06A66),//propiedad color que lleva un widged llamado: Color para darle color a nuestro icono.)); final estrella =Container(//Container:tendra las estrellas y le pondremos margenes para acomodar la estrella con colormargin:EdgeInsets.only(// EdgeInsets.only(), esto me permite generar un margen mas especifico a nivel de top, left, right, bottom//margin: margenes de nuestros elementos del containertop:349.0,//arribaright:3.0,//derecha),child:Icon(//child toma un solo widget toma un solo elemnto, en este caso toma el icono "estrella"Icons.favorite,//widget icono estrellacolor:Color(0xFFF06A66),//propiedad color que lleva un widged llamado: Color para darle color a nuestro icono. (0xFFf2C611): esto son colores hexagecimal),); final descripcion =Container(//final: significa asignación simple: una variable o campo final * debe * tener un inicializador. Una vez asignado un valor, el valor de una variable final no se puede cambiar. Modificaciones finales * variables *.margin:EdgeInsets.only(// EdgeInsets.only(), esto me permite generar un margen mas especifico a nivel de top, left, right, bottom//margin: margenes de nuestros elementos del containertop:15.0,//arribaleft:20.0,//izquierdaright:20.0,//derecha),child:Text(//child(Hijo) toma un solo widget toma un solo elemnto. Text: widget de elementos tipo texto"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut semper ornare sodales. Cras condimentum enim purus, sed placerat nunc volutpat et. Nunc malesuada, quam vel consectetur convallis, libero nisi volutpat nibh, ut aliquet diam eros eu tortor. Cras eget accumsan purus. Quisque sed justo convallis, efficitur ipsum sed, hendrerit nisl. \nDuis tincidunt, est vitae molestie laoreet elit dolor varius dui, ac malesuada ex orci vel libero.",style:TextStyle(//propiedad style: darle estilo a un elemento. widget TextStyle: darle estilos a un elemento tipo textocolor:Color(0xFF56575a)//color al texto),textAlign:TextAlign.justify//alineamos el parrafo con un espacio justificado),); final titulo_estrellas =Row(//final: significa asignación simple: una variable o campo final * debe * tener un inicializador. Una vez asignado un valor, el valor de una variable final no se puede cambiar. Modificaciones finales * variables *.//row: Un row, es un widget que se utiliza para mostrar widgets de forma horizontal. El widget row no se desplaza. Si tiene una línea de widgets y desea que puedan desplazarse si no hay suficiente espacio, considere usar una Clase ListView.children:<Widget>[//children: lleva una lista de widgets, lleva una lista de elementos, children:seran todos elementos que estan apilados en forma de Row(fila) o renglonContainer(//Container:tendra el texo y le pondremos margenes para acomodar la informacionmargin:EdgeInsets.only(// EdgeInsets.only(), esto me permite generar un margen mas especifico a nivel de top, left, right, bottom//margin: margenes de nuestros elementos del containertop:345.0,//arribaeleft:25.0,//izquierdaright:26.0//derecha),child:Text(//child toma un solo widget toma un solo elemnto. Text: widget de elementos tipo texto"Duwili Ella",//textostyle:TextStyle(//propiedad style: darle estilo a un elemento. widget TextStyle: darle estilos a un elemento tipo textofontSize:30.0,//propiedad fontSize para canbiar tamaño del titulofontWeight:FontWeight.w900//fontWeight es una propiedad. FontWeight.w900 es un widget para darle Negrita como en word),textAlign:TextAlign.left,//propiedad textAlign: para alinear textos. TextAlign.left: es un widget para alinear textos a la izquierda),),Row(//acomoda los elemendos en fila en este caso estrellaschildren:<Widget>[//tomamos varios hijos o widgets y los ponemos dentro de una fila//Aqui llamamos los hijos, elementos o widgets que queremos que se muestren en pantalla ↓↓↓(las veces que queramos) estrella,//llamamos al primer hijo(widget) estrella,//llamamos al segundo hijo(widget) estrella,//llamamos al tercero hijo(widget) estrella,//llamamos al cuarto hijo(widget) estrella_sincolor,//llamamos al quinto hijo(widget)],),],);returnColumn(//retomamos los elementos y los pone en una columna children:<Widget>[//tomamos varios hijos o widgets y los ponemos dentro de una columna titulo_estrellas,//llamamos al primer hijo(widget) descripcion,//llamamos al segundo hijo(widget)],);}}
Gran resumen juan-camilo-bula, se agradece
Partiendo de la aportación de uno de mis compañeros, agregué la validación sólo para el widget de Icon, además de contemplar rating con decimales (ejemplo rating 4.5).
Hola compañero,
¿Cómo hiciste para que el texto se divida en dos párrafos? Yo lo logré hacer, pero no como lo hace la profesora en el video, así me aparece en un solo párrafo.
Cuál es la diferencia entre
newText(dummyDescription)
y
Text(dummyDescription)
¿?
Ninguna, desde la versión 2 de Dart es opcional el uso de "new".
¿Por qué a veces se usa child y a veces children?
Hola @emilian20. Entiendo que se coloca dependiendo el tipo de widget que estés utilizando.
Ejemplo:
En el widget Container solo te permite 1 elemento "Anidado" (Espero utilizar el termino correcto) o hijo:
En el caso de widgets como Row o Column que permite "anidar" varios elementos se usa children:
Row(children:[Image.asset("assets/images/astronauta.jpg",fit:BoxFit.cover,),//Widget 1Text("Hola Mundo"),//Widget 2Center(child:Text("Un nuevo viaje",style:TextStyle(color:Colors.white,fontSize:20,fontWeight:FontWeight.bold),)//Widget 3)],)
Uno es singular y otro plural, haciendo referencia de que si es singular (CHILD) solo puede contener un Widget y de manera opuesta con el plural (CHILDREN), pudiendo así pasarle más de un Widget. Espero que te resuelva la duda.
Traté de replicar lo del video, pero parece en 2022 las cosas ya no se hacen de esta forma, cuando logre ver como se hace volveré con la respuesta... Creo 😅
Ve la documentación de flutter, verás que no es tan distinto. Yo tengo el mismo problema jaja. https://docs.flutter.dev/
Sí, lo vi en la documentación, pero ya se me había olvidado que había comentado esto 😅
Hola, por que algunas veces cuando creamos nuevos widgets se les coloca new y otros que no por ejemplo
new EdgeInsets
Actualmente no es necesario utilizar la palabra clave 'new' para instanciar un Widget. Sin embargo sigue siendo valido su uso.
Puedes utilizar o no la palabra clave new
ej:
Soy solo yo o siento que se perdio una parte en el tutorial donde se explica como se crea la clase DescriptionPlace?, esta chido tener el material pero creo que ahi falto o lo cortaron
Claro que el argumento star del widget lo declaré como double en lugar de int.
Finalmente, en el row para las estrellas en el atributo children solo le paso el array de estrella que se generó dinámicamente.
Row(children: starWidgetArrray
)
Creo que es la solución más optima que encontré, la variable numberOfStars admite decimales y de acuerdo a ello genera las estrellas.
Comparto aqui mi solución para pintar las estrellas según el puntaje dado como parámetro all Widget compuesto en main.dart
import'package:flutter/material.dart';classinformacion_detalleextendsStatelessWidget{/*
* variables de la clase
* */ double puntuacion;String descripcion;String titulo_lugar;/*
* constructor
* */informacion_detalle(this.titulo_lugar,this.descripcion,this.puntuacion);
@override
Widgetbuild(BuildContext context){/*
* creando la declaracion del widget titulo y asignando a variable para luego ser utilizado
* */var titulo =Container(margin:EdgeInsets.only(top:320,left:20,right:20),child:Text(titulo_lugar,style:TextStyle(fontSize:30,fontWeight:FontWeight.bold),textAlign:TextAlign.left),);/*
* creando la declaracion del widget detalle y asignando a variable
* */ final detalle =Container(margin:EdgeInsets.only(left:20,right:20,top:20),child:Text(descripcion,textAlign:TextAlign.justify,style:TextStyle(color:Colors.black87,fontSize:18,fontWeight:FontWeight.normal,fontStyle:FontStyle.italic)),);/*
* creando la subvista con todos los widgets individuales anteriores
* */ final tituloANDpuntaje =Column(children:<Widget>[Row(children:<Widget>[titulo,Row(children:printStars())],), detalle,],);/*
* retornar el widget compuesto
* */return tituloANDpuntaje;}/*
* creando la declaracion del widget estrella
* */Widgetcreate_star(){var star =Container(margin:EdgeInsets.only(top:324,right:3),child:Icon(Icons.star,color:Colors.amber),);return star;}Widgetcreate_emptyStar(){var empty_star =Container(margin:EdgeInsets.only(top:324,right:3),child:Icon(Icons.star_border,color:Colors.amber),);return empty_star;}Widgetcreate_halfStar(){var half_star =Container(margin:EdgeInsets.only(top:324,right:3),child:Icon(Icons.star_half,color:Colors.amber),);return half_star;}/*
* funcion que imprime los Widgets estrella segun el puntaje
* */List<Widget>printStars(){List<Widget> estrellas =newList(); int rellenas = puntuacion.floor();for(int i =0; i < rellenas; i++){ estrellas.add(create_star());}if(puntuacion - puntuacion.floor()!=0){ estrellas.add(create_halfStar());}for(int i =0; i <5- puntuacion.ceil(); i++){ estrellas.add(create_emptyStar());}return estrellas;}}
Hola tengo un error al intentar guardar el constructor de la manera que Anahí lo crea en el video (21). ambio la manera en la cual se crea esta parte del código?
De hecho está bien! Pero si lees con atención el error, te darás cuenta que cuando invocas la función DescriptionPlace() en el main.dart no le pasas los 3 parámetros que tiene que tener. Por eso el primer error es: "arguments: 3 required, 0 given".
Hola, al correr el emulador con el ejemplo de la clase aparece lo siguiente:
A qué creen que se deba? Gracias
Buenas buenas.
Solo presiona "wait". Lo que sucede es que el telefono no responde correctamente y hay quedarle tiempo para que carge bien la interfaz, no es nada grave.
Gracias BoomVam
Así lo he notado.
Tengo una duda. nombre una variable como "description_text" y funcionaba mientras trabaja en el widget [description_place.dart]. Pero cuando cambié de lugar a la variable y la pegué en el [main.dart] me daba error. La solución fue renombrarla de forma camel case "descriptionText" ¿Alguien me podría explicar por que pasa esto?
Se me extraño, ya que la creación de una variable global queda como mucho en el archivo creado, lo que se me ocurre es que dentro de tu archivo main.dart ya tenías una variable con ese mismo nombre y que al cambiarlo solucionó el conflicto.
porque despues de establecer el constructor cuando voy a poner las variables en el lugar que corresponden minuto 5:26 de la clase, me sale el error!
import'package:flutter/material.dart';classDescriptionPlaceextendsStatelessWidget{String nameplace; int start;String descriptionPlace;DescriptionPlace(this.descriptionPlace,this.nameplace,this.start);
@override
Widgetbuild(BuildContext context){ final star=Container(margin:EdgeInsets.only(top:323.0,right:3.0,),child:Icon(Icons.star,color:Color(0xFFf2C611),),); final description_text=Container(margin:EdgeInsets.only(top:20.0,left:20.0,right:20.0,),child:constText( descriptionPlace,textAlign:TextAlign.justify,style:TextStyle(fontSize:16.0,fontWeight:FontWeight.bold,color:Color(0xFF56575a)),)); final title_stars=Row(children:<Widget>[Container(margin:constEdgeInsets.only(top:320.0,left:20.0,right:20.0),child:constText( nameplace,style:TextStyle(fontSize:30.0,fontWeight:FontWeight.w900),textAlign:TextAlign.left,),),Row(children:<Widget>[ star, star, star, star, star,])],);returnColumn(children:<Widget>[ title_stars, description_text
],);}}
Cuando creas la clase "DescriptionPlace" y le creas un constructor por parámetros, significa que cuando mandes a llamar a esa clase en específico (En el archivo main.dart), lo debas hacer con los valores que espera recibir.
En este caso sería algo como:
Widgetstar(bool active){returnContainer(margin:EdgeInsets.only(top:323,right:3),child:Icon( active ?Icons.star:Icons.star_border,color:Color(0xFFf9da5e)),);}
final titleElement =Row(children:[Container(margin:EdgeInsets.only(top:320,left:20,right:20),child:Text(name,style:TextStyle(fontWeight:FontWeight.w900,fontSize:21),textAlign:TextAlign.left)),Row(children:[for(int i =0; i <5; i++)star(stars > i ?true:false)],)],);