Cuando queremos un espacio entre los hijos children del widget Column, normalmente usan SizeBox, pero con Wrap se puede usar un atributo para el spaceado entre los hijos
Wrap(
spacing: 20, // to apply margin in the main axis of the wrap
runSpacing: 20, // to apply margin in the cross axis of the wrap
children: <Widget>[
Text('child 1'),
Text('child 2')
]
)
Desarrollando un sistema, que consta de dos apps según el rol del usuario, ( conductor y pasajero, vendedor y comprador, administrador y empleado, etc ), percate que si bien ya puedo desplegar en ambas plataformas, hay partes de la interfaz y la API que se repite, solo la lógica parece única, entonces surge la necesidad de compartir este código común.
La primera solución fue copiar el código en un paquete dentro de lib, pero como esta en desarrollo se repetirá muchas veces ese paso lo cual suena doloroso, así que probare el concepto de cómo compartirlo entre ambas apps.
bueno, al código.
Creamos 3 aplicaciones: Cliente1, Cliente2 y Librería
Trabajaré en la aplicación Cliente1 agregando la librería y luego repetiré lo mismo en la Cliente2 para comprobarlo.
Lo que necesito probar en este caso es : – Si se puede compartir widgets – Si la librería tiene dependencias, estas deben cargarse en la principal o se puede obviar. – Si se puede configurar variables en la librería desde el cliente.
Tomando el caso del sistema, una parte común entre ambas apps, es el chat.
Primero trabajaremos en la librería
Librería
Para probar cada requerimiento se hará:
– Si se puede compartir widgets. Se implementará un widget del botón que iniciara el chat que cada cliente colocara donde lo necesite.
– Si la librería tiene dependencias, estas deben cargarse en la principal o se puede obviar. Se usará un paquete de iconos en la librería.
– Si se puede configurar variables en la librería desde el cliente Se seteará un parámetro que es global en la librería, para ver como se comporta en el cliente..
Primero implementé como si fuera un proyecto normal para verificar su funcionamiento, separando los componentes que serán reusables.
Crear un archivo “lib_chat.dart” donde indican que archivos serán expuestos para los clientes. ( nota: aún no tengo ni he visto un convención para los nombres, por el momento le colocare el prefijo de lib_*)
Al momento de usarlo en cliente, no se puede usar las dependencias que se uso en la librería, pero si se exponen, por ejemplo “flutter_icons.dart”, se pueden usar en el cliente.
Se creo un nuevo widget “widget_button_chat.dart”, solo para encerrar en una clase el botón del chat y usarlo en el cliente.
library lib_chat;
//expone el wiget button
export 'widget/widget_button_chat.dart';
//expone la página del chat
export 'page/chat_page.dart';
//expone la configuración que usa el chat
export 'constants.dart';
//agregado después para exponer la dependencia que se uso en la librería
export 'package:flutter_icons/flutter_icons.dart';
En pubspec.yaml no es necesario ningún cambio, pero para poder identificarlo mejor, cambie el nombre a “libreria_chat“, eso conllevo cambiar el paquete en algunos archivos.
name: Libreria_chat
description: Libreria de chat
...
Para usar la librería en el Cliente 1, se agrega la dependencia en pubspec.yaml. indicando el nombre “Libreria_chat” y la ruta “path:“
...
dependencies:
flutter:
sdk: flutter
Libreria_chat:
path: ../LibreriaRefactorizado #ruta a la librería
# The following adds the Cupertino Icons font to your application.
# Use with the CupertinoIcons class for iOS style icons.
cupertino_icons: ^1.0.0
...
En main.dart , agregue el botón button_chat_widget y un icono de una dependencia de la librería Icon(AntDesign.message1) ( esto se pudo después de exponerlo en la librería por defecto sus dependencias no están disponibles) y se configuro la variable constante en la librería CHAT_USER_NAME.
import 'package:Libreria_chat/constants.dart';
import 'package:Libreria_chat/widget/widget_button_chat.dart';
import 'package:flutter_icons/flutter_icons.dart';
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: MyHomePage(title: 'Cliente 1'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int _counter = 0;
void _incrementCounter() {
setState(() {
_counter++;
});
}
@override
Widget build(BuildContext context) {
CHAT_USER_NAME = "Javier Solis";
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Icon(AntDesign.message1),
Text(
'You have pushed the button this many times:',
),
Text(
'$_counter',
style: Theme.of(context).textTheme.headline4,
),
],
),
),
floatingActionButton: ButtonChatWidget(
urlContactPhoto:
"https://crop-circle.imageonline.co/images/picture.png",
nameContact: "Raul",
));
}
}
Tenemos una librería que podemos rehusar. Ahora podemos tener una librerías de utilitarios que podemos usar en todas nuestras app ( notificaciones, login, control de permisos , etc) que ahorrara tiempo en configurar, en grupo de apps conductor/cliente, etc.
Notas adicionales:
Si tengo abierto la librería y hago un cambio, luego haces hotreload en el cliente, los cambios en la librería se cargarán.
No implemente el cliente 2, porque los pasos son los mismos al cliente 1.
La librería también se puede publicar en pub.dev o referenciar desde github.
Lanzar el emulador IOS, en caso no sepa como hacerlo, en los siguientes link se describe como:
.
.
Corriendo debera notar que imprime un token
Con el token podemos dirigir la notificación para este dispositivo, esto es opcional ya que sino lo especificamos enviara a todos, pero lo haremos así para poder probar mas rápido porque las notificaciones pueden demorar hasta 1 semana según la documentación.
Vamos a firebase > Cloud Messaging > send your first message
Luego llenamos el formulario y click en “Enviar mensaje de prueba”
Pegamos el token en la ventana luego click en boton “+” y click en “probar”
Revisando el output en visual studio code, se vera la notificación
Click en “Installing” y seguir las instrucciones, para esta versión indica, agregar firebase_messaging: ^7.0.3 en el archivo pubspec.yaml las dependencias
Nota: Revisar la fecha y las dependencias usadas, ya que por políticas de las plataformas o nuevas versiones de estas librerías las indicaciones pueden variar
Para los que pueden guiarse de la documentación oficial, solo necesitan:
Abrir el proyecto en Visual studio Code, luego en la abrir la terminal, por comodidad lo abriré desde visual studio code, pero tiene el mismo efecto si lo abre aparte.
Luego en la termina ejecutar: flutter devices
Si aparece que detecto el emulador puede correrlo directamente, sino continue leyendo, aparece
No devices detected.
Luego ejecutar : Flutter doctor
Es posible que obtenga el mensaje de advertencias para XCode
[!] Xcode – develop for iOS and macOS ✗ Xcode installation is incomplete; a full installation is necessary for iOS development. Download at: https://developer.apple.com/xcode/download/ Or install Xcode via the App Store. Once installed, run: sudo xcode-select –switch /Applications/Xcode.app/Contents/Developer sudo xcodebuild -runFirstLaunch
Luego, siga las instrucciones , correr los dos comando que indica: