Romper diseños en filas y columnas en aleteo

Si ha leído sobre Flutter incluso durante 5 minutos, debe haberse topado con Widgets. Y el hecho más popular "En Flutter, casi todo es un widget".

Si todo.

Defino Widgets como los componentes o bloques que definen la interfaz de usuario. La barra de aplicaciones es un widget, el texto que contiene es un widget, el estilo que aplica al texto es un widget, incluso la alineación del texto podría llamarse como un widget. En Flutter, todo lo que es una vista o contribuye a una propiedad de la vista es un widget.

Puedo seguir y seguir sobre widgets, pero para simplificar, aquí hay una lista recomendada de widgets que debes conocer para crear una aplicación en Flutter. Para una referencia rápida, ver más abajo.

Centrándose en filas y columnas

En Flutter, puede dividir casi el 90% de los diseños de diseño en Filas y Columnas. Ocasionalmente, tendrá que usar otros widgets como Stack, Grid, etc., pero desde el nivel base, necesitará filas y columnas en algún bloque de IU u otro.

Entonces las filas y las columnas son ...

Cuando hay elementos colocados uno al lado del otro, u horizontalmente a la izquierda / derecha de otro elemento, necesita Filas.

Cuando hay elementos colocados uno tras otro, o verticalmente arriba / abajo a otro elemento, necesita columnas.

Bastante básico, ¿verdad?

A los efectos de este artículo, también debe saber lo siguiente:
Contenedores: si viene de un entorno de desarrollo web, o tiene algún conocimiento básico de HTML, los contenedores sonarán bastante familiares para los divs.
Pilas: si hay vistas que se superponen a otras vistas, use Pilas.

Vamos a construir una interfaz de usuario

Es hora de sumergirse en el código y construir un par de componentes de diseño bastante populares y ver cómo encajan las Filas y Columnas aquí. Para el primer diseño, replicaremos el elemento de la lista de pantallas de chats de WhatsApp. Algo similar a la imagen de abajo.

Desglose de diseño # 1

Entonces, ¿cuántos elementos o vistas vemos? Foto de perfil. Nombre de usuario. Último mensaje del usuario. Hora del último mensaje. Y número de mensajes no leídos.

Vamos a envolver todo esto dentro de un contenedor y tener tres secciones secundarias: leftSection, middleSection y rightSection, una tras otra horizontalmente.

leftSection contendrá la foto de perfil.
middleSection tendrá lastMessage debajo de userName.
rightSection tendrá unMessageCount no leído debajo de timeStamp.

Bueno. ¿Fue difícil?
Tal vez al principio, pero una vez que domines las filas y las columnas, puedes desglosar naturalmente los diseños en tu cabeza.

Hora de codificar

A diferencia de la mayoría de los otros tutoriales para principiantes, siempre trataré de dividir mi código en diferentes clases y widgets. Hace que el código sea súper legible.

main.dart

void main () => runApp (nuevo MyApp ());

La clase MyApp extiende StatelessWidget {
  // Este widget es la raíz de su aplicación.
  @anular
  Compilación de widgets (contexto BuildContext) {
    devolver MaterialApp (
      inicio: nuevo ChatItemScreen (), // llamando a chat_screen_item.dart
    );
  }
}

Consejo para principiantes: no olvide importar las clases que utilizará. Entonces, por ejemplo, main.dart importará chat_screen_item.dart que tiene nuestra clase ChatItemScreen.

chat_item_screen.dart

La clase ChatItemScreen extiende StatelessWidget {
  @anular
  Compilación de widgets (contexto BuildContext) {
    volver nuevo andamio (
      appBar: nueva AppBar (
        título: nuevo texto ("elemento de chat"),
        backgroundColor: Colors.lightGreen,
      ),
      body: new ChatItem (), // llamando a chat_item.dart
    );
  }
}

Eso fue solo para comenzar, para no tropezar con los pasos básicos de inicio. Ahora pasamos al código principal. Nuestra clase ChatItem devolverá un widget de contenedor que tiene un elemento secundario Row. Este niño de la fila tendrá tres nuevos widgets leftSection, middleSection y rightSection que construiremos pronto.

chat_item.dart

clase ChatItem extiende StatelessWidget {

  final leftSection = new Container ();
  middleSection final = nuevo contenedor ();
  final rightSection = nuevo contenedor ();

  @anular
  Compilación de widgets (contexto BuildContext) {
    volver nuevo andamio (
    cuerpo: nuevo contenedor (
      hijo: nueva fila (
        hijos:  [
          leftSection,
          sección del medio,
          rightSection
        ],
      ),
    ),
  );

  }

}

Sección izquierda

En la sección izquierda, necesitamos un CircleAvatar, y también tenemos un pequeño widget para eso.

final leftSection = nuevo contenedor (
  hijo: nuevo CircleAvatar (
    backgroundImage: nueva imagen de red (url),
    backgroundColor: Colors.lightGreen,
    radio: 24.0,
  ),
);

Sección del medio

Ahora dentro de MiddleSection Container, creamos una columna de dos widgets de texto que contendrán el nombre de usuario y el contenido del último mensaje.

middleSection final = nuevo contenedor (
  hijo: nueva columna (
    hijos:  [
      Nuevo texto ("Nombre"),
      nuevo texto ("Hola, ¿qué pasa?"),
    ],
  ),
);

Hace el trabajo de colocar widgets uno tras otro, pero se ve realmente feo. Es hora de agregar un poco de embellecimiento.

middleSection final = nuevo expandido (
  hijo: nuevo contenedor (
    relleno: nuevo EdgeInsets.only (izquierda: 8.0),
    hijo: nueva columna (
      crossAxisAlignment: CrossAxisAlignment.start,
      mainAxisAlignment: MainAxisAlignment.spaceAround,
      hijos:  [
        Nuevo texto ("Nombre",
          estilo: nuevo TextStyle (
              color: colores negro.
              fontWeight: FontWeight.w600,
              fontSize: 16.0,
          ),),
        Nuevo texto ("Hola whatsp?", estilo:
          nuevo TextStyle (color: Colors.grey),),
      ],
    ),
  ),
);
  • Expandido: dado que esta sección quiere todo el espacio libre disponible, envolvemos todo el contenedor en este widget expandido. Sin esto, el diseño se verá así:
  • Acolchado: más espacio para respirar, woah.
  • TextStyle: le da estilo al texto, como colores, fontSize, etc. Tanto como CSS, maldita sea.
  • Ahora puedo explicar crossAxisAlignment y mainAxisAlignment, pero no puedo explicarlo mejor que este video. Así que te sugiero que aprendas de los mejores. (Consulte de 2:00 a 7:30 para obtener una referencia rápida del tema en el que estamos)

Sección derecha

Casi terminamos. Solo necesito construir otra columna de dos widgets. Esta vez, los widgets para niños serán un widget de texto para la marca de tiempo y otro pequeño CircleAvatar para el recuento.

rightrightSection = nuevo contenedor (
  hijo: nueva columna (
    mainAxisAlignment: MainAxisAlignment.spaceAround,
    hijos:  [
      nuevo texto ("9:50",
          estilo: nuevo TextStyle (
            color: Colors.lightGreen,
          fontSize: 12.0),),
      nuevo CircleAvatar (
        backgroundColor: Colors.lightGreen,
        radio: 10.0,
        hijo: nuevo texto ("2",
        estilo: nuevo TextStyle (color: Colors.white,
        fontSize: 12.0),),
      )
    ],
  ),
);

Ahora ejecuta esta cosa hermosa. Y ya está listo.

¿Desglosaremos otro diseño solo para asegurarnos de que te estás acostumbrando?

Desglose de diseño # 2

Tarjeta de colecciones Zomato

Así que tenemos este diseño de tarjeta simple que tiene una columna de algunos widgets de texto superpuestos a una imagen de fondo. Hmm .. dijiste superposición? Entonces, ¿eso significa que usamos pilas aquí?

SÍ, lo estás entendiendo.

Entonces, en lugar de la sección izquierda, media o derecha, desglosemos este diseño en backgroundImage y onTopContent.

@anular
Compilación de widgets (contexto BuildContext) {

  devolver nuevo contenedor (
    relleno: nuevo EdgeInsets.all (8.0),
    altura: 250.0,
    hijo: nueva pila (
      hijos:  [
        imagen de fondo,
        onTopContent
      ],
    ),
  );
}

Imagen de fondo

Ahora la imagen de fondo tendrá un Contenedor con una imagen de fondo y un filtro de color para oscurecer el fondo.

imagen de fondo final = nuevo contenedor (
    decoración: nueva BoxDecoration (
      imagen: nueva DecorationImage (
        colorFilter: nuevo ColorFilter.mode (
            Colors.black.withOpacity (0.6),
            BlendMode.luminosity),
        imagen: nueva imagen de red (url),
        ajuste: BoxFit.cover,
      ),
    ),
);

En contenido superior

¿Qué piensas? ¿Filas o columnas?

Lo tienes. Coluuuumns

final onTopContent = nuevo contenedor (
  altura: 80.0,
  hijo: nueva columna (mainAxisSize: MainAxisSize.max,
    mainAxisAlignment: MainAxisAlignment.spaceEvenly,
    crossAxisAlignment: CrossAxisAlignment.start,
    hijos:  [
      Texto nuevo ("Tendencias esta semana",
      estilo: bigHeaderTextStyle),
      nuevo Texto ("Los restaurantes más populares de la ciudad esta semana",
        estilo: descTextStyle),
      nuevo contenedor (
        altura: 2.0,
        ancho: 150.0,
        color: Colors.redAccent,
      ),
      nuevo texto ("30 LUGARES",
        estilo: footerTextStyle),
      // nuevo contenedor ()
    ],
  ),
);

Ahora no te sorprendas por los estilos que he usado. Estos no son valores predeterminados de Flutter, sé que tiene errores. Todos los estilos para la tarjeta zomato se definen aquí.

Incluso puede encontrar el repositorio completo de GitHub para estos diseños aquí.

En el futuro, exploraré diseños más complejos que puede romper hasta el nivel raíz. Por supuesto, necesitará más widgets para diseños más complejos, pero Filas y Columnas siempre tendrán un papel en alguna parte, por lo que es importante que tenga esto en mente.

Lee mis otros artículos sobre Flutter

Flutter es fresco y actualmente lo estoy descubriendo. Si encuentra algo mal con mi código o enfoque, menciónelo en los comentarios, me encantaría mejorar.
Si aprendiste incluso una o dos cosas, aplaude tantas veces como puedas para mostrar tu apoyo.
Hola mundo, soy Pooja Bhaumik. Un desarrollador creativo y un diseñador lógico. ¿Puedes encontrarme en Linkedin o acecharme en GitHub o seguirme en Twitter? Si eso es demasiado social para usted, solo envíe un correo electrónico a pbhaumik26@gmail.com si desea hablar de tecnología conmigo.