miércoles, 22 de julio de 2015

Android, Evento OnClick de un boton


Una de las cosas cuando estaba con Java y Swing era la gestión de los eventos a través de los Listener.

Pues bueno, con Android 3/4 de lo mismo, por ejemplo, boton que nos va para otra actividad.



Y pensar que hace años en multiples lenguajes / GUIs tenemos evento OnClick....

En fin, arriba vemos como creamos un objeto, btnEuro,  y lo asignamos a través del setOnClickListener, que a su vez, se le pasa un objeto creado a través de new View.OnClickListener(), que se sobreescribe el method onClick,
y ahí, se crea un Intent, que se le pasa al inicio de la Activity.

¿ Lo podemos hacer más simple ? Pues si, de esta manera;


Y ahora, solo nos queda activarlo;


Y nos queda solo sobrescribir el method OnClick en la propia clase MainActivity;




Update: Bien, también con Android Studio,  podemos hacer lo siguiente;

En las propiedades del botón , ponemos el method que recibirá el evento, solo nos queda codificarlo;

 

jueves, 16 de julio de 2015

Empezando con Android


Bueno, después de posponer una y otra vez el empezar con Android, no entenderé la m*erdas de RAD en comparación con otros, con el Android Studio ya me he decidido.

Para empezar, una pequeña calculadora muy simple;
https://github.com/rafathefull/Calculadora

He aquí la imagen del proyecto;


lunes, 6 de julio de 2015

Patrón de Diseño Builder con Harbour

Seguimos con nuestros patrones de diseño. En este post veremos como implementar el patrón de diseño Builder, del tipo creacional.

Como Patrón de diseño, el patrón builder (Constructor) es usado para permitir la creación de una variedad de  objetos complejos desde un objeto fuente (Producto), el objeto fuente se compone de una variedad de partes que contribuyen individualmente a la creación de cada objeto complejo a través de un conjunto de llamadas a interfaces comunes de la clase Abstract Builder.
https://es.wikipedia.org/wiki/Builder_%28patr%C3%B3n_de_dise%C3%B1o%29          

Como siempre, podemos el código que muestra el uso de este patrón;
#include "hbclass.ch"

/* ABSTRACT BUILDER */
CLASS ROBOT
 
    // Metodos que se tienen que declarar en la clase heredada 
      METHOD Trabajar() VIRTUAL       
      METHOD CargarAcciones() VIRTUAL

 END CLASS

/* ----------------------------------------------------  */
CLASS ROBOT_HAMBUERGUESA FROM ROBOT
      DATA Lista_Acciones

      METHOD New() INLINE Self

      METHOD iniciar  HIDDEN
      METHOD getIngredientes HIDDEN
      METHOD Armar    HIDDEN
      METHOD Revisar  HIDDEN
      METHOD Terminar HIDDEN
     
      METHOD CargarAcciones() // Sobrecargado
      METHOD Trabajar()       // Sobrecargado

END CLASS

METHOD Iniciar() CLASS ROBOT_HAMBUERGUESA
  ? "Iniciando hambuerguesa"
RETURN nil

METHOD getIngredientes() CLASS ROBOT_HAMBUERGUESA
  ? "Coge Ingredientes"
RETURN nil

METHOD Armar() CLASS ROBOT_HAMBUERGUESA
  ? "Arma"
RETURN nil

METHOD Revisar() CLASS ROBOT_HAMBUERGUESA
  ? "Revisar"
RETURN nil

METHOD Terminar() CLASS ROBOT_HAMBUERGUESA
  ? "Terminar"
RETURN nil

METHOD CargarAcciones( Lista ) CLASS ROBOT_HAMBUERGUESA
  ::Lista_Acciones := Lista
RETURN nil

METHOD Trabajar() CLASS ROBOT_HAMBUERGUESA
     Local nAccion

     ::iniciar()

     for each nAccion in ::Lista_Acciones
         do case
            case nAccion = 1
                 ::getIngredientes()
            case nAccion = 2
                 ::Armar()
            case nAccion = 3
                 ::Revisar()
            otherwise
                 ? "No existe accion a realizar"
         end case
     next

     ::Terminar()

RETURN nil


/* ----------------------------------------------------  */
CLASS ROBOT_HOTDOG FROM ROBOT
      DATA Lista_Acciones

      METHOD New() INLINE Self

      // Como ejemplo, al ser metodos privados, podemos tener otros nombres
      METHOD Start  HIDDEN
      METHOD getParts HIDDEN
      METHOD build    HIDDEN
      METHOD check  HIDDEN
      METHOD finish HIDDEN
     
      METHOD CargarAcciones() // Sobrecargado
      METHOD Trabajar()       // Sobrecargado

END CLASS

METHOD Start() CLASS ROBOT_HOTDOG
  ? "Start HotDog"
RETURN nil

METHOD getParts() CLASS ROBOT_HOTDOG
  ? "get Pars"
RETURN nil

METHOD build() CLASS ROBOT_HOTDOG
  ? "Build"
RETURN nil

METHOD check() CLASS ROBOT_HOTDOG
  ? "check"
RETURN nil

METHOD finish() CLASS ROBOT_HOTDOG
  ? "finish"
RETURN nil

METHOD CargarAcciones( Lista ) CLASS ROBOT_HOTDOG
  ::Lista_Acciones := Lista
RETURN nil

METHOD Trabajar() CLASS ROBOT_HOTDOG
     Local nAccion

     ::Start()

     for each nAccion in ::Lista_Acciones
         do case
            case nAccion = 1
                 ::getParts()
            case nAccion = 2
                 ::build()
            case nAccion = 3
                 ::check()
            otherwise
                 ? "No existe accion a realizar"
         end case
     next

     ::finish()

RETURN nil

/* ----------------------------------------------------  */
CLASS BUILDER
      DATA Acciones
      DATA ROBOT

      METHOD New() CONSTRUCTOR
      METHOD SetRobot( i )
      METHOD addGetIngredientes inline aadd( ::Acciones, 1 )
      METHOD addArmar           inline aadd( ::Acciones, 2 )
      METHOD addRevisar         inline aadd( ::Acciones, 3 ) 
      METHOD addImposible       inline aadd( ::Acciones, 100 )

      METHOD getRobot()

END CLASS

METHOD New() CLASS BUILDER
    ::Acciones := {}
RETURN Self

/* Crea un robot segun solicitado */
METHOD SetRobot( i ) CLASS BUILDER
    do case
       case i = "1"
            ::robot := ROBOT_HAMBUERGUESA():New()
       case i = "2"
            ::robot := ROBOT_HOTDOG():New()

    end case
RETURN nil

METHOD getRobot() CLASS BUILDER
   
     ::robot:CargarAcciones( ::Acciones )

RETURN ::robot


/* ----------------------------------------------------  */
// Ejemplo de Implementación : ./test 1

function Main( cRobot )     Local oRobot
     Local oBuilder := BUILDER():New()

     oBuilder:SetRobot( cRobot )
     oBuilder:addRevisar()
     oBuilder:addImposible()
     oBuilder:addGetIngredientes()
     oBuilder:addArmar()
     oBuilder:addRevisar()

     oRobot := oBuilder:getRobot()
     oRobot:Trabajar()

return nil

jueves, 2 de julio de 2015

Patrón de Diseño Factory Method con Harbour


Despues de ver como implementar un patron de diseño Singleton en Harbour,
http://xthefull.blogspot.com/2014/11/el-patron-de-diseno-singleton-en-harbour.html
le toca el turno al patrón de diseño del tipo Factory Method

Este patron de diseño correspopnde a los llamados Patrones Creacionales;

Centraliza en una clase constructora la creación de objetos de
un subtipo de un tipo determinado, ocultando al usuario la casuística, es decir,
la diversidad de casos particulares que se pueden prever, para elegir el subtipo que crear.
Parte del principio de que las subclases determinan la clase a implementar. 


https://es.wikipedia.org/wiki/Factory_Method_(patr%C3%B3n_de_dise%C3%B1o)


A continuación se muestra un ejemplo de este patrón en Harbour;
#include "hbclass.ch"

/* ------------------------------------------------------ */
/* Patron Diseño FACTORY Method                           */
/* ------------------------------------------------------ */


CLASS FACTORY
     DATA tipo PROTECTED

     METHOD New( Tipo )
     METHOD creaConexion( )

END CLASS

METHOD New( Tipo ) CLASS Factory
   ::Tipo := Tipo
RETURN Self

METHOD creaConexion() CLASS Factory
   Local oConexion

   do case
      case ::tipo = "MySql"
           oConexion := MySql():New()
      
      case ::tipo = "SqlServer"
           oConexion := SqlServer():New() 
      case ::tipo = "Sqlite3"
           oConexion := Sqlite3():New()
 

      otherwise
           oConexion := Conexion():New()
   end case

RETURN oConexion


/* ------------------------------------------------------ */
/* ------------------------------------------------------ */
 

CLASS CONEXION
     METHOD New() INLINE Self
     METHOD Descripcion() INLINE "Conexion Generica"
END CLASS
 

/* ------------------------------------------------------ */
/* ------------------------------------------------------ */
 

CLASS MySql FROM CONEXION
      METHOD New( ) INLINE Self
      METHOD Descripcion() INLINE "Conexion MySql"
END CLASS

/* ------------------------------------------------------ */
/* ------------------------------------------------------ */
 
CLASS SqlServer FROM CONEXION
      METHOD New( ) INLINE Self
      METHOD Descripcion() INLINE "Conexion SqlServer"

END CLASS
 
/* ------------------------------------------------------ */
/* ------------------------------------------------------ */
 
CLASS Sqlite3 FROM CONEXION
      METHOD New( ) INLINE Self
      METHOD Descripcion() INLINE "Conexion Sqlite3"

END CLASS



/* ------------------------------------------------------ */ 
// Ejemplo de uso : ./test MySql
/* ------------------------------------------------------ */

Function Main( cTipo )
   Local oFactory, oConexion

   oFactory  := Factory():New( cTipo )
   oConexion := oFactory:creaConexion()

   ? "Estamos conectados con " + oConexion:Descripcion()

RETURN nil


Android y Git. Disponer del hash automáticamente.

Una de las cosas a las que estoy acostumbrado, es tener siempre en mi código, el hash/tag/versión del control de versiones que estoy usan...