en flutter

Crear librerías comunes entre aplicaciones Flutter

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

$ flutter create --org=com.example.cliente1 Cliente1
$ flutter create --org=com.example.cliente2 Cliente2
$ flutter create --org=com.example.libreria Libreria

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.

Repositorio:

https://github.com/JavierSolis/Flutter_DemoLibreria_Libreria

Los cambios para hacerlo librería son:

  • 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';
import 'package:Libreria_chat/page/chat_page.dart';
import 'package:flutter/material.dart';
import 'package:flutter_icons/flutter_icons.dart';

class ButtonChatWidget extends StatelessWidget {
  final String urlContactPhoto;
  final String nameContact;
  const ButtonChatWidget({Key key, this.nameContact, this.urlContactPhoto})
      : super(key: key);

  @override
  Widget build(BuildContext context) {
    return FloatingActionButton(
      onPressed: () {
        Navigator.pushReplacement(
            context,
            MaterialPageRoute(
                builder: (BuildContext context) => ChatPage(
                    contactName: this.nameContact,
                    urlContactPhoto: this.urlContactPhoto)));
      },
      child: Icon(AntDesign.message1),
    );
  }
}
  • 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
...
import 'package:Libreria_chat/constants.dart';
import 'package:Libreria_chat/widget/widget_chat.dart';
import 'package:flutter/material.dart';

class ChatPage extends StatelessWidget {

Repositorio:

https://github.com/JavierSolis/Flutter_DemoLibreria_Libreria_refactorizado

Cliente 1

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",
        ));
  }
}

Video:

Repositorio:

https://github.com/JavierSolis/Flutter_DemoLibreria_Cliente_1

y listo.


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.

Referencias:

Iconos de ejemplo
https://pub.dev/packages/flutter_icons

Lista
https://googleflutter.com/flutter-add-item-to-listview-dynamically/

Border rounded
https://stackoverflow.com/a/57778500

Escriba un comentario

Comentario