lunes, 29 de noviembre de 2010

Crear un componente personalizado desde XML [Android]

Los componentes personalizados de Android nos permiten personalizar elementos de interfaz, bien modificándolos o bien agrupando varios en un único componente que podamos reutilizar. La documentación de Android denomina a este tipo de controles compuestos a su vez de varios controles estándar de Android Compound Components. Se explica cómo construir uno de estos controles en el código Java de una nueva clase, pero no queda muy claro cómo podríamos construir el componente si quisieramos utilizar uno de los ficheros de interfaz XML.

Para hacerlo, empezaríamos definiendo la interfaz en un fichero XML, que en mi caso sería /res/layout/elementos_lista.xml. En este caso vamos a hacer algo sencillo: un cuadro de texto con un botón.

<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_height="wrap_content" android:orientation="horizontal" android:layout_width="fill_parent"> <LinearLayout android:id="@+id/LinearLayout01" android:layout_width="fill_parent" android:layout_height="wrap_content"> <EditText android:layout_height="50px" android:id="@+id/edit_persona" android:layout_width="fill_parent" android:layout_weight="1"></EditText> <Button android:id="@+id/btn_agenda" android:layout_height="50px" android:layout_width="fill_parent" android:layout_weight="3" android:text="Agenda"></Button> </LinearLayout> </LinearLayout>

Con esto creamos una clase en nuestra carpeta src que extienda a la clase LinearLayout y desde la que cargaremos ese fichero XML en su constructor. Como queremos que el botón ejecute una acción (en este caso imprimir algo por pantalla) definimos también un OnClickListener con la manejadora del click sobre el botón.

package ocode.apps.aleatorizr; import android.content.Context; import android.util.AttributeSet; import android.view.LayoutInflater; import android.view.View; import android.widget.Button; import android.widget.LinearLayout; import android.widget.Toast; public class ElementosListaComponent extends LinearLayout { public OnClickListener agendaHandler = new OnClickListener() { @Override public void onClick(View v) { Toast.makeText(v.getContext(), "click en el botón agenda", Toast.LENGTH_SHORT).show(); } }; public ElementosListaComponent(Context context) { super(context); } public ElementosListaComponent(Context context, AttributeSet attr){ super(context,attr); LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); LinearLayout vistaCompuesta = (LinearLayout) inflater.inflate(R.layout.elementos_lista, this); Button btn_agenda = (Button) vistaCompuesta.findViewById(R.id.btn_agenda); btn_agenda.setOnClickListener(agendaHandler); } }

Lo importante de este código está ocurriendo en el segundo constructor, que por medio de LayoutInflater procesa el código XML de la interfaz del componente para que lo tengamos accesible para ser utilizado desde cualquier otra vista del programa. Con esto hecho, si quisiesemos utilizarlo en otro layout sólo tendremos que abrir dicho layout y utilizar el siguiente código:

<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="wrap_content" android:orientation="vertical"> <TextView android:text="Selecciona uno" android:id="@+id/txt_pic" android:layout_width="wrap_content" android:layout_height="wrap_content"></TextView> <ocode.apps.aleatorizr.ElementosListaComponent android:layout_width="fill_parent" android:layout_height="wrap_content"> </ocode.apps.aleatorizr.ElementosListaComponent> </LinearLayout>

martes, 23 de noviembre de 2010

Configurar EditText para que utilice el teclado numérico [Android]

Cuando sabemos que en un campo de texto de tipo EditText sólo puede recibir un número, nos puede interesar configurarlo para que cargue sólo el teclado numérico en lugar del teclado completo. Para hacer esto sólo hay que definir el EditText añadiendo los siguientes atributos:

<EditText 
   android:numeric="integer"
   android:inputType="number">
</EditText>

Referencias en la documentación de Android:

martes, 16 de noviembre de 2010

URL Encoding en Objective-C [Receta iPhone y iPad]

Si necesitamos comunicarnos con algún servicio web enviándole datos es muy probable que tratemos de formar la url a partir de una cadena de caraceteres:


NSString *urlString = [NSString stringWithFormat:@"http://servicio/parametro1/%@/",
parametro];

Cuidado con esto. Te puedes encontrar con que el servicio devuelva un BAD REQUEST debido a que no entiende el contenido de los parámetros.

Solución

La solución radica en formar la url así


NSURL *theURL = [[NSURL alloc] initWithScheme:@"http" host:@"servicio"
path:[NSString stringWithFormat:@"/%@",parametro]];


En ese caso la codificación a porcentajes la hará automáticamente.

jueves, 11 de noviembre de 2010

Cargar una imagen desde una Url [Receta iPhone y iPad]

Hasta que los desarrolladores del iOS SDK se dignen a hacer una función del tipo


[UIImage imageFromURL:url];

nos tendremos que conformar con esto:

Solución


NSURL *url = [NSURL URLWithString:urlImagen];
NSData *data = [NSData dataWithContentsOfURL:url];
UIImage *img = [[UIImage alloc] initWithData:data];
//Hacemos cosas con la imagen...
[img release];

Explicación

Creamos un objeto url que se lo pasamos al método de NSData capaz de obtener datos desde una url. Como UIImage cuenta con un método capaz de crear una imagen desde un NSData le pasamos la imagen descargada.

Cómo cambiar el fondo del UISearchBar [Receta iPhone y iPad]

Inauguramos este blog dedicado a recopilar pequeños trozos de código que vamos necesitando a medida que desarrollamos aplicaciones para iPhone, Android, iPad o Windows Phone 7.

Cambiando el fondo al UISearchBar

El UISearchBar es un elemento de interfaz que ofrece el SDK de iOS. Cambiar el fondo (no el tint sytle) puede suponer un engorro.

Solución


UILabel *lbl = [[UILabel alloc]init];
lbl.frame = searchbar.frame;
lbl.backgroundColor = [UIColor cyanColor];
[self.searchbar insertSubview:lbl atIndex:1];
[lbl release];

Explicación

Creamos un vista (en este caso un UILabel), le asignamos las dimensiones y posición de la barra de búsqueda y lo insertamos por encima de la primera vista.

Cuidado

No es conveniente hardcodear el índice de las vistas porque puede variar de una versión a otra del SDK. Puede que a la gente de Cupertino les de por cambiar la posición de cada subvista.