Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                

Tema 4

Descargar como docx, pdf o txt
Descargar como docx, pdf o txt
Está en la página 1de 21

Tema 4: Layouts y Menús

Introducción al tema
La Interfaz de usuario (UI) de su aplicación es todo con lo que el usuario puede ver e
interactuar.  Android ofrece una variedad de componentes de interfaz de usuario pre-
construidos, tales como objetos de diseño estructurados conocidos como layouts y controles
de interfaz de usuario que le permiten construir la interfaz gráfica de usuario para su
aplicación.  Android también ofrece otros módulos de interfaz de usuario para interfaces
especiales, como los cuadros de diálogo, las notificaciones y menús.
Todos los elementos de la interfaz de usuario de una aplicación para Android se construyen
utilizando objetos View y ViewGroup. Una View es un objeto que dibuja algo en la pantalla que
el usuario puede interactuar.  Un ViewGroup es un objeto que contiene otros objetos View y
ViewGroup con el fin de definir el diseño de la interfaz. 
Android ofrece una colección de ambas subclases View y ViewGroup que le ofrecen los
controles comunes de entrada (como botones y campos de texto) y diversos modelos de
diseño o layouts (como Linear Layout o Relative Layout, los dos más utilizados).  En esta
ocasión vamos a concentrarnos en estos últimos, los Layouts, puesto que son aquellos con los
que generalmente iniciamos la estructura de nuestra interfaz de usuario.
La interfaz de usuario para cada componente de su aplicación se define utilizando una
jerarquía de objetos View y ViewGroup, como se muestra en la figura:

Cada ViewGroup es un contenedor invisible que organiza Views hijos, mientras que los View
Hijos pueden ser controles de entrada u otros widgets que dibujan una cierta parte de la
interfaz de usuario.  Este árbol de jerarquía puede ser tan simple o complejo como usted
necesite que sea (pero la simplicidad es lo mejor siempre para el rendimiento).

Mapa conceptual referido al tema

4.1. Layouts
Un Layout es un objeto ViewGroup que define la estructura visual de una interfaz de usuario,
tales como la interfaz de usuario para una actividad o un app Widget. Por lo tanto cuando
hablamos de layout nos estamos refiriendo al diseño que deseamos aplicar a nuestras
interfaces de usuario.  Puede definir un Layout de dos maneras:
 Declarar elementos de interfaz de Usuario en XML.  Android proporciona un
vocabulario XML sencillo que corresponde a las clases y subclases View, como las de
los widgets y layouts mismos.
 Instanciar elementos layout en tiempo de ejecución.  Su aplicación puede crear
objetos View y ViewGroup (y manipular sus propiedades) mediante programación.

El Framework Android le da la flexibilidad para utilizar uno o ambos de estos métodos para la
declaración y gestión de la interfaz de usuario de la aplicación.  Por ejemplo, usted podría
declarar diseños predeterminados de su aplicación en XML, incluyendo los elementos de la
pantalla que aparecen en ellos y sus propiedades.  A continuación, puede añadir código de la
aplicación que modifique el estado de los objetos de la pantalla, incluyendo los declarados en
XML, en tiempo de ejecución.
La ventaja de declarar su interfaz de usuario (UI) en XML, es que le permite separar mejor la
presentación de su aplicación del código que controla su comportamiento.  Sus descripciones
de interfaz de usuario son externos a su código de la aplicación, lo que significa que usted
puede modificar o adaptar sin tener que modificar el código fuente y recompilar.  Por ejemplo,
puede crear XML Layouts para diferentes orientaciones de pantalla, diferentes tamaños de
pantalla de dispositivos y diferentes idiomas.  Además, declarando su layout en XML hace que
sea más fácil visualizar la estructura de su interfaz de usuario, por lo que es más fácil de
depurar algunos problemas.  Como tal, esta semana nos centramos en la enseñanza de cómo
declarar su layout en XML. 
En general, el vocabulario XML para declarar elementos de la UI sigue de cerca la estructura y
denominación de las clases y métodos, donde los nombres de los elementos corresponden a
los nombres de clases y los nombres de atributos corresponden a los métodos.  De hecho, la
correspondencia es a menudo tan directa que se puede adivinar qué atributo XML
corresponde a un método de clase, o adivinar qué clase corresponde a un elemento XML en
cuestión.  Sin embargo, tenga en cuenta que no todo el vocabulario es idéntico.  En algunos
casos, hay diferencias de nomenclatura ligeras. Por ejemplo, el elemento EditText tiene un
atributo texto que corresponde EditText.setText().
 
Escribiendo el XML
Utilizando XML de Android, puede diseñar rápidamente Layouts de usuario y los elementos de 
pantalla que contienen, de la misma manera como crea páginas web en HTML, con una serie
de elementos anidados.
Cada archivo de layout debe contener exactamente un elemento raíz, que debe ser un objeto
View o ViewGroup.  Una vez que haya definido el elemento raíz, puede agregar objetos o
widgets de diseño adicionales como elementos secundarios para construir gradualmente una
jerarquía que define su diseño.  Por ejemplo, aquí está un layout de XML que utiliza una
vertical LinearLayout que contiene un TextView y un botón:

<?xml version="1.0" encoding="utf-8"?>


<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:layout_width="match_parent"
              android:layout_height="match_parent"
              android:orientation="vertical" >
    <TextView android:id="@+id/text"
              android:layout_width="wrap_content"
              android:layout_height="wrap_content"
              android:text="Hello, I am a TextView" />
    <Button android:id="@+id/button"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Hello, I am a Button" />
</LinearLayout>

Después de haber declarado su disposición en XML, el archivo de be guardarse con la


extensión .xml, en el directorio de su proyecto Android res/layout/, para que este se compile
luego correctamente. 
Para obtener más información sobre la sintaxis de un archivo de layout XML puedes
revisar Recursos Layout.  Tambien si deseas puedes ir revisando el código XML utilizando el
código XML para cada control contenido en un Layout en Controles.
Para nuestro primer proyecto que hemos creado “Mi primera Aplicacion”, puedes abrir el
archivo /res/layout/activity_my.xml y observar el código XML que Android ha generado para
este Layout.

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:paddingBottom="@dimen/activity_vertical_margin"
    tools:context=".MyActivity">
    <TextView
        android:text="@string/hello_world"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />
</RelativeLayout>
 
Atributos
Cada objeto View y ViewGroup soporta su propia variedad de atributos XML.  Algunos
atributos son específicos de un objeto View (por ejemplo, TextView admite el atributo
textSize), pero estos atributos también son heredados por los objetos View que pueden
extender esta clase. Algunos son comunes a todos los objetos View, ya que se heredan de la
clase raíz View (como el atributo id). Y, otros atributos son considerados "parámetros de
diseño" (layouts parameters), los cuales son atributos que describen ciertas orientaciones de
diseño del objeto View, según la definición de objeto ViewGroup padre de ese objeto.
ID
Cualquier objeto View puede tener un ID asociado con él, para identificar unívocamente el
View dentro del árbol. Cuando se compila la aplicación, esta identificación se hace referencia
como un valor entero, pero la identificación se suele asignar en el archivo XML de diseño como
una cadena o String, en el atributo id.  Este es un atributo XML común a todos los objetos View
(definidos por la clase View) y que se utiliza muy a menudo.  La sintaxis de una identificación,
dentro de una etiqueta XML es:
android:id="@+id/my_button"
El símbolo (@) en el principio de la cadena, indica que el analizador sintáctico XML debe
analizar y ampliar el resto de la cadena de ID e identificar como un recurso ID.  El plus-símbolo
(+) significa que este es un nuevo nombre de recurso que debe ser creado y añadido a
nuestros recursos (en el archivo R.java, el que es manejado de forma interna por Android y
nosotros como desarrolladores no podemos manipular).  Veamos un ejemplo con un control:
Definimos un View en el archivo Layout y asignamos a este un único ID:

<Button android:id="@+id/my_button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/my_button_text"/>

A continuación, creamos una instancia del objeto View y lo obtenemos desde el diseño
mediante su ID, por lo general en el método onCreate() del archivo Java correspondiente a
nuestro Activity:

Button myButton = (Button) findViewById(R.id.my_button);

Un ID no tiene que ser único en todo el árbol, pero debe ser único dentro de la parte del árbol
que está buscando.  Dado que a menudo se suele buscar en todo el árbol, es mejor que el ID
de cada View sea completamente único en lo posible.

Layout Parameters
Los atributos denominados layout_algo definen los parámetros layout para el View que son
apropiados de acuerdo al ViewGroup donde reside. 
Cada clase ViewGroup implementa una clase anidada que extiende
de ViewGroup.LayoutParams.  Esta subclase contiene los tipos de propiedades que definen el
tamaño y la posición de cada View hijo, según sea apropiado para el ViewGroup.  Como se
puede ver en la figura, el ViewGroup padre define los parámetros de diseño para cada View
hijo (incluyendo el hijo ViewGroup).

Tenga en cuenta que cada subclase LayoutParams tiene su propia sintaxis para establecer
valores.  Cada elemento hijo debe definir LayoutParams que sean apropiados para su padre,
aunque también puede definir diferentes LayoutParams para sus propios hijos. 
Todos los ViewGroup incluyen una anchura y altura (layout_width y layout_height), y se
requiere de cada View que defina estos.  Muchos LayoutParams también incluyen márgenes y
bordes opcionales. 
Podemos especificar el ancho y la altura con las medidas exactas en unidades, aunque es
altamente probable que en la mayoría de las veces no sea necesario y tampoco
recomendable.  Se utiliza una las siguientes constantes para establecer estos parámetros:

fill_parent: El elemento view puede crecer al tamaño de su padre que lo contiene.  Está
obsoleto, a partir de API Level 8 remplazado por match_parent.
match_parent: El elemento view puede ser tan grande como su padre que lo contiene. 
wrap_content: El elemento view puede crecer de acuerdo a su contenido, se ajusta al
contenido interno automáticamente.
wrap_content o match_parent, es un mejor enfoque, ya que ayuda a asegurar que su
aplicación se mostrará correctamente en una variedad de tamaños de pantalla del dispositivo.

En general, no se recomienda especificar un ancho de la disposición y altura usando unidades


absolutas como píxeles. En cambio, se debe usar las medidas relativas tales como unidades
independientes de la densidad de píxeles (dp) .
4.1.1. Linear Layout
LinearLayout es un ViewGroup que organiza a sus elementos hijos en una sola fila horizontal o
vertical.  Se especifica la dirección del layout con el atributo android:orientation.
Todos los hijos están apilados uno tras otro, por lo que una orientación vertical sólo tendrán
un hijo por fila, no importa cuál sea la anchura de estos.  En una orientación horizontal sólo
será una fila de alto (la altura del hijo más alto).
Un LinearLayout respeta los márgenes entre los hijos y el gravity (alineación derecha, centro o
izquierda) de cada hijo.
 
Layout Weight
LinearLayout es compatible con la asignación de un peso(Weight) a cada hijo con el atributo
android:layout_weight.  Este atributo asigna un valor de "importancia" a un View hijo en
términos de la cantidad de espacio que debe ocupar en la pantalla.  Un valor mayor de peso
permite que se expanda para llenar cualquier espacio que queda en la vista padre.   El peso por
defecto es cero.
Ejemplo: Si hay tres campos de texto y dos de ellos tienen un weight de 1, mientras que el otro
no tiene ningún peso, el tercer campo de texto sin peso no va a crecer y sólo ocupará el área
requerida por su contenido. Los otros dos se ampliará igualmente para rellenar el espacio que
queda después que se miden los tres campos.
Si el tercer campo viene dada entonces un peso de 2 (en lugar de 0), entonces se declara ahora
más importante que los otros dos, por lo que consigue la mitad del espacio total restante,
mientras que los dos primero comparten el resto igual.

Para más detalles acerca de los atributos disponibles para cada hijo de LinearLayout,
ver LinearLayout.LayoutParams.

4.1.2. Relative Layout


RelativeLayout es un ViewGroup que permite colocar cualquier elemento en cualquier lado,
pero siempre con respecto a otro elemento.  La posición de cada View se puede especificar en
relación con otros View hermanos (tales como a la izquierda de o por debajo de otro View) o
en posiciones relativas con respecto al Relative Layout padre (tales como alineado a la parte
inferior, izquierda o central).
Es muy potente para el diseño de una interfaz de usuario, ya que puede eliminar Views
anidados y mantener su jerarquía de disposición plana, lo que mejora el rendimiento. 
Si te encuentras usando varios LinearLayout anidados, es posible que puedas sustituirlos por
un único RelativeLayout .

Posicionamiento de los Views


RelativeLayout permite que los Views especifiquen su posición con respecto al View padre o
entre sí (especificado por el ID).  Así que podemos alinear dos elementos al borde derecho, o
colocar uno debajo de otro, centrado en la pantalla, centrado a la izquierda y así
sucesivamente.  Por defecto, todos los View hijos se dibujan en la parte superior izquierda(top-
left) del Layout, por lo que debemos definir la posición de cada View mediante las diversas
propiedades del Layout disponibles de RelativeLayout.LayoutParams.  Algunas de estas
propiedades son las siguientes:

android:layout_alignParentTop
Si es "true", hace que el borde superior de este View coincida con el borde superior del padre.
android:layout_centerVertical
Si es "true", centra este View verticalmente dentro de su padre.
android:layout_below
Positions the top edge of this view below the view specified with a resource ID.
Posiciona el borde superior de este View por debajo del View especificado con el recurso ID.
android:layout_toRightOf
Posiciona el borde izquierdo de este View a la derecha del View especificado con recurso ID.
Estos son sólo algunos ejemplos. Todos los atributos de diseño están documentados
en RelativeLayout.LayoutParams.

El valor para cada propiedad layout es o bien un valor booleano para habilitar una posición
respecto al padre RelativeLayout o un ID que hace referencia a otro VIew en el layout con el
que el View debe ser colocado.
En su layout XML, los Views se pueden declarar en cualquier orden. Por ejemplo, se puede
declarar que "view1" se coloca por debajo "view2" aunque "view2" es el último View
declarado en la jerarquía.  El ejemplo siguiente muestra un escenario de este tipo:

<?xml version="1.0" encoding="utf-8"?>


<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingLeft="16dp"
    android:paddingRight="16dp" >
    <EditText
        android:id="@+id/name"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="@string/reminder" />
    <Spinner
        android:id="@+id/dates"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_below="@id/name"
        android:layout_alignParentLeft="true"
        android:layout_toLeftOf="@+id/times" />
    <Spinner
        android:id="@id/times"
        android:layout_width="96dp"
        android:layout_height="wrap_content"
        android:layout_below="@id/name"
        android:layout_alignParentRight="true" />
    <Button
        android:layout_width="96dp"
        android:layout_height="wrap_content"
        android:layout_below="@id/times"
        android:layout_alignParentRight="true"
        android:text="@string/done" />
</RelativeLayout>

Otro ejemplo, donde podemos observar de forma más clara que es indiferente el orden en que
se colocan los View puesto que lo que finalmente manda su posición son los atributos
RelativeLayout.LayoutParams:

<?xml version="1.0" encoding="utf-8"?>

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"

    android:layout_width="match_parent"

    android:layout_height="match_parent" >

    <TextView

        android:id="@+id/view1"

        android:layout_width="match_parent"

        android:layout_height="wrap_content"

        android:layout_alignParentTop="true"

        android:text="Arriba Textview1" />

    <TextView

        android:id="@+id/view2"

        android:layout_width="match_parent"

        android:layout_height="wrap_content"

        android:layout_alignParentBottom="true"

        android:text="Abajo Textview2" />


 

    <TextView

        android:id="@+id/view3"

        android:layout_width="match_parent"

        android:layout_height="0dip"

        android:layout_above="@id/view2"

        android:layout_below="@id/view1"

        android:text="Centro - TextView3" />

</RelativeLayout>

4.1.3. List View


ListView es un ViewGroup que muestra una lista de elementos desplazables.  Los elementos de
la lista se insertan automáticamente a la lista utilizando un adaptador que extrae el contenido
de una fuente tal como un array o una consulta de base de datos y convierte cada elemento
resultante en una View que se coloca en la lista.
Para una introducción de cómo se puede insertar de forma dinámica Views utilizando un
adaptador, podemos recurrir a la documentación construyendo Layouts con un Adapter.
Un ejemplo bastante sencillo tomado desde http://www.javaya.com.ar/androidya lo
mostramos a continuación:

Se necesita disponer de un ListView con los nombres de los países de sudamérica.  Cuando se
seleccione un país mostrar en un TextView la cantidad de habitantes del país seleccionado.
Creamos un nuevo Activity y utilizando nuestro diseñador gráfico agregamos un TextView
(llamado tv1) y un ListView (llamado listView1).  Luego nuestro código Java del Activity debe
quedar de la siguiente manera:
 
public class MainActivity extends Activity {
                private String[] paises = { "Argentina", "Chile", "Paraguay", "Bolivia",
                                               "Peru", "Ecuador", "Brasil", "Colombia", "Venezuela", "Uruguay" };
                private String[] habitantes = { "40000000", "17000000", "6500000",
                                               "10000000", "30000000", "14000000", "183000000", "44000000",
                                               "29000000", "3500000" };
                private TextView tv1;
                private ListView lv1;
 
                @Override
                protected void onCreate(Bundle savedInstanceState) {
                               super.onCreate(savedInstanceState);
                               setContentView(R.layout.activity_main);
        tv1=(TextView)findViewById(R.id.tv1);
        lv1 =(ListView)findViewById(R.id.listView1);    
        ArrayAdapter <String> adapter = new
ArrayAdapter<String>(this,android.R.layout.simple_list_item_1, paises);
        lv1.setAdapter(adapter);
        lv1.setOnItemClickListener(new OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View v, int posicion, long id) {
                tv1.setText("Población de "+ lv1.getItemAtPosition(posicion) + " es "+
habitantes[posicion]);
            }
        });                   
                }
}

A continuación se pasa a explicar el código:


Primero definimos dos vectores paralelos donde almacenamos en uno los nombres de países y
en el otro almacenamos la cantidad de habitantes de dichos países:

    private String[] paises={"Argentina","Chile","Paraguay","Bolivia","Peru",


                             "Ecuador","Brasil","Colombia","Venezuela","Uruguay"};
    private String[] habitantes={"40000000","17000000","6500000","10000000","30000000",
                                 "14000000","183000000","44000000","29000000","3500000"};

Definimos un objeto de tipo TextView y otro de tipo ListView donde almacenaremos las
referencias a los objetos que definimos en el archivo XML:

    private TextView tv1;


    private ListView lv1;

En el método onCreate obtenemos la referencia a los dos objetos:

        tv1=(TextView)findViewById(R.id.tv1);
        lv1 =(ListView)findViewById(R.id.listView1);    

Creamos un objeto de la clase ArrayAdapter de forma similar a como lo hicimos cuando vimos
la clase Spinner:

ArrayAdapter<String> adapter = new


ArrayAdapter<String>(this,android.R.layout.simple_list_item_1, paises);
        lv1.setAdapter(adapter);

Llamamos al método setOnItemClicListener de la clase ListView y le pasamos como parámetro


una clase anónima que implementa la interfaz OnItemClickListener (dicha interfaz define el
método onItemClick que se dispara cuando seleccionamos un elemento del ListView):

        lv1.setOnItemClickListener(new OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View v, int posicion, long id) {
                tv1.setText("Población de "+ lv1.getItemAtPosition(posicion) + " es "+
habitantes[posicion]);
            }
        });

Dentro del método onItemClick modificamos el contenido del TextView con el nombre del país
y la cantidad de habitantes de dicho país. Este método recibe en el tercer parámetro la
posición del item seleccionado del ListView.
Cuando ejecutamos el proyecto podemos ver una interfaz en el emulador similar a esta:

4.1.4. Grid View


GridView es un ViewGroup que muestra los elementos en una, rejilla desplazable
bidimensional.   Los elementos de la cuadrícula se insertan automáticamente a la disposición
mediante un ListAdapter.
Para una introducción de cómo se puede insertar de forma dinámica Views utilizando un
adaptador, podemos recurrir a la documentación construyendo Layouts con un Adapter.
En este tutorial, vamos a crear una cuadrícula de miniaturas de imágenes.  Cuando se
selecciona un elemento, un mensaje de aviso emergente mostrará la posición de la imagen.

1.- Inicie un nuevo proyecto llamado HelloGridView .


2.- Busque algunas fotos que quiera utilizar o descargue estas imágenes de muestra desde
developer.android.  Guarde los archivos de imagen en el proyecto, en la carpeta:
res/drawable/.
3.- Abra el archivo res/layout/main.xml e inserte el siguiente código:
<?xml version="1.0" encoding="utf-8"?>
<GridView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/gridview"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:columnWidth="90dp"
    android:numColumns="auto_fit"
    android:verticalSpacing="10dp"
    android:horizontalSpacing="10dp"
    android:stretchMode="columnWidth"
    android:gravity="center"
/>

Este GridView llenará toda la pantalla.  Los atributos son bastante explicativos por sí mismos.
Para obtener más información acerca de los atributos válidos, consulte el GridView referencia.
4.- Abra el archivo HelloGridView.java e inserte el siguiente código en el método onCreate():

public void onCreate(Bundle savedInstanceState) {


    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    GridView gridview = (GridView) findViewById(R.id.gridview);
    gridview.setAdapter(new ImageAdapter(this));
    gridview.setOnItemClickListener(new OnItemClickListener() {
        public void onItemClick(AdapterView<?> parent, View v, int position, long id) {
            Toast.makeText(HelloGridView.this, "" + position, Toast.LENGTH_SHORT).show();
        }
    });
}

Luego que el layout main.xml se establece para la vista de contenido


setContentView(R.layout.main), el GridView se captura dede el layout con findViewById(int).  
El método setAdapter() establece un adaptador personalizado (ImageAdapter) como la fuente
de todos los elementos que se muestran en la cuadrícula o grid.  El ImageAdapter se crea en el
paso siguiente.
Para hacer algo cuando se hace clic en un elemento del grid, el método
setOnItemClickListener() es pasado a un new AdapterView.OnItemClickListener.  Esta instancia
anónima define el método callback onItemClick() para mostrar mensaje del tipo toast que
muestra la posición de índice (basado en cero) del elemento seleccionado (en un escenario
real, la posición se podría utilizar para obtener la imagen de tamaño completo para alguna otra
tarea ).

5.- Crear una nueva clase llamada ImageAdapter que extiende de BaseAdapter :

public class ImageAdapter extends BaseAdapter {


    private Context mContext;
 
    public ImageAdapter(Context c) {
        mContext = c;
    }
    public int getCount() {
        return mThumbIds.length;
    }
 
    public Object getItem(int position) {
        return null;
    }
 
    public long getItemId(int position) {
        return 0;
    }
    public View getView(int position, View convertView, ViewGroup parent) {
        ImageView imageView;
        if (convertView == null) {  // if it's not recycled, initialize some attributes
            imageView = new ImageView(mContext);
            imageView.setLayoutParams(new GridView.LayoutParams(85, 85));
            imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
            imageView.setPadding(8, 8, 8, 8);
        } else {
            imageView = (ImageView) convertView;
        }
 
        imageView.setImageResource(mThumbIds[position]);
        return imageView;
    }
 
    private Integer[] mThumbIds = {
            R.drawable.sample_2, R.drawable.sample_3,
            R.drawable.sample_4, R.drawable.sample_5,
            R.drawable.sample_6, R.drawable.sample_7,
            R.drawable.sample_0, R.drawable.sample_1,
            R.drawable.sample_2, R.drawable.sample_3,
            R.drawable.sample_4, R.drawable.sample_5,
            R.drawable.sample_6, R.drawable.sample_7,
            R.drawable.sample_0, R.drawable.sample_1,
            R.drawable.sample_2, R.drawable.sample_3,
            R.drawable.sample_4, R.drawable.sample_5,
            R.drawable.sample_6, R.drawable.sample_7
    };
}

En primer lugar, este implementa algunos métodos necesarios heredados de BaseAdapter.  El


constructor y getCount () son fáciles de entender.  Normalmente, getItem(int) debe devolver el
objeto real en la posición especificada en el adaptador, pero se ha ignorado para este
ejemplo.  Del mismo modo, GetItemID(int) debe devolver el ID de la fila del item, pero no es
necesario aquí.
El primer método necesario es getView().  Este método crea una nueva vista para cada imagen
añadida al ImageAdapter. Cuando este se llama, un View se pasa, que normalmente es un
objeto reciclado (por lo menos después de lo que ha sido llamado una vez), por lo que hay una
comprobación para ver si el objeto es nulo.  Si es nulo, un ImageView se instancia y se
configura con las propiedades deseadas para la presentación de la imagen:

setLayoutParams(ViewGroup.LayoutParams) ajusta la altura y la anchura del View-esto


asegura que, sin importar el tamaño del estirable, cada imagen se redimensiona y recorta para
encajar en estas dimensiones, según el caso.
setScaleType(ImageView.ScaleType) declara que las imágenes deben ser recortadas hacia el
centro (si es necesario).
setPadding(int, int, int, int) define el relleno(padding) para todos los lados.  (Tenga en cuenta
que, si las imágenes tienen diferentes aspecto de ratios, a continuación, menos pading causará
más recorte de la imagen si no coincide con las dimensiones dadas para el ImageView).
Si el View pasado a getView() no es nulo, entonces el de ImageView se inicializa con el objeto
View reciclado.

Al final del método getView(), la posición de número entero pasa en el método se utiliza para
seleccionar una imagen de la mThumbIds matriz, que se establece como el recurso de imagen
para el ImageView .
Todo lo que queda es definir el mThumbIds gama de recursos dibujables.
6.- Ahora ya puede ejecutar su aplicación.

4.2. Menús
Los menús son un componente de la interfaz de usuario común en muchos tipos de
aplicaciones.  Para proporcionar una experiencia de usuario familiar y consistente, se debe
utilizar los APIs de Menú para presentar las acciones del usuario y otras opciones en sus
Activities.
Aunque la experiencia de diseño y de usuario para algunos elementos del menú han cambiado,
la semántica para definir un conjunto de acciones y opciones se sigue basando en los APIs de
menú.  Debemos aprender a crear los tres tipos fundamentales de menús:

1.- Menú de opciones y barra de acciones (Action Bar)


El menú de opciones es la colección principal de los elementos de menú para una Activity.  Es
el lugar donde se debe colocar acciones que tienen un impacto global en la aplicación, como
"Búsqueda", "Preparar correo electrónico" y "Ajustes".
Los elementos del menú de opciones se presentan mediante la barra de acción (Action Bar)
como una combinación de elementos y opciones que se sobreposicionan en la pantalla.
2.- Menú contextual y modo de acción contextual
Un menú contextual es un menú flotante que aparece cuando el usuario realiza un clic largo en
un elemento.  Proporciona acciones que afectan el contenido seleccionado.
Se debe utilizar este para activar acciones en el contenido seleccionado.  Este modo muestra
los puntos de acción que afectan el contenido seleccionado en una barra en la parte superior
de la pantalla y permite al usuario seleccionar varios elementos.
3.- Menú Popup o emergente
Un menú popup o emergente muestra una lista de elementos en una lista vertical que se
anclan al View que invocó el menú.  Es útil para proporcionar más opciones de las acciones que
se relacionan con un contenido específico o para proporcionar opciones para una segunda
parte de un comando.  Las acciones en un menú emergente no deberían afectar directamente
al contenido o contexto, puesto que esto le corresponde al menú de tipo contextual.  Más
bien, el menú emergente es para acciones extendidas que se relacionan con las regiones del
contenido de su activity.
Definiendo un Menú en XML
Para todos los tipos de menú, Android proporciona un formato estándar XML para definir los
elementos de menú.  En lugar de construir un menú en el código de su Activity, debe definir un
menú y todos sus items en un recurso de menú XML.  Luego, puede insertar el recurso de
menú (cargarlo como objeto Menú) en su Activity o fragmento.
El uso de un recurso de menú es una buena práctica por varias razones:

 Es más fácil de visualizar la estructura de menús en XML.


 Separa el contenido para el menú del código de comportamiento de la aplicación.
 Permite crear configuraciones de menú alternativos para diferentes versiones de la
plataforma, tamaños de pantalla y otras configuraciones mediante el aprovechamiento
de los recursosdel framework.

Para definir el menú, crear un archivo XML dentro de su proyecto en la carpeta /res/menu y
crear el menú con los siguientes elementos:
<Menú>
Define un menú, que es un contenedor para elementos de menú. Un elemento <menu> debe
ser el nodo raíz del archivo y puede contener uno o más elementos <item> y <grupo>.
<Elemento>
Crea un MenuItem, lo que representa un solo elemento en un menú. Este elemento puede
contener un elemento anidado <menu> con el fin de crear un submenú.
<Grupo>
Un contenedor opcional, invisible para elementos <item>.  Este permite clasificar los
elementos de menú por los que comparten propiedades como el estado activo y visibilidad. 
A continuación un ejemplo de menú denominado game_menu.xml:

<?xml version="1.0" encoding="utf-8"?>


<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:id="@+id/new_game"
          android:icon="@drawable/ic_new_game"
          android:title="@string/new_game"
          android:showAsAction="ifRoom"/>
    <item android:id="@+id/help"
          android:icon="@drawable/ic_help"
          android:title="@string/help" />
</menu>

El elemento  <item> es compatible con varios atributos que puede utilizar para definir la
apariencia y el comportamiento de un elemento.  Los elementos en el menú anterior incluyen
los siguientes atributos:
android: Identificación
Un identificador de recurso que es único para el tema, el cual permite que la aplicación puede
reconocer el elemento cuando el usuario selecciona.
android: icon
Una referencia a un drawable a utilizar como icono del elemento.
android: título
Una referencia a una cadena que se utilizará como título del ítem.
android: showAsAction
Especifica cuándo y cómo este item debe aparecer como un elemento de acción en la barra de
acción.
Estos son los atributos más importantes que debe usar, pero hay muchos más disponibles.
Para obtener información sobre todos los atributos admitidos, consulte el documento recurso
menú.
Puede agregar un submenú a un item en cualquier menú (excepto un submenú) añadiendo un
elemento <menu> como el hijo de un <item>.  Los submenús son útiles cuando su aplicación
tiene un montón de funciones que se pueden organizar en temas, como los elementos de la
barra de menú de una aplicación para PC (Archivo, Editar, Ver, etc.). Por ejemplo:
 
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:id="@+id/file"
          android:title="@string/file" >
        <!-- "file" submenu -->
        <menu>
            <item android:id="@+id/create_new"
                  android:title="@string/create_new" />
            <item android:id="@+id/open"
                  android:title="@string/open" />
        </menu>
    </item>
</menu>
Para utilizar el menú en su Activity, debe inflar el recurso menú (convertir el recurso XML en un
objeto programable) usando MenuInflater.inflate().  

4.2.1 Menú de opciones


Los elementos del menú de opciones están disponibles en la barra de acción (Action Bar).   Por
defecto, el sistema coloca todos los elementos en el desbordamiento de la barra de acción,
que el usuario puede revelar con el icono del menú del Action Bar en el lado derecho de la
barra de acción.  Para permitir el acceso rápido a acciones importantes, usted puede promover
unos elementos para que aparezcan en la barra de acciones añadiendo android:showAsAction
= "ifRoom" a los correspondientes elementos <item>.
Para obtener más información acerca de los items de acciones y otros comportamientos de la
barra de acciones, véase la guía del Action Bar.
Puede declarar items para el menú de opciones desde subclase Activity o subclase fragmento.
Si tanto su Activity y el fragmento(s) declaran items para el menú de opciones, que se
combinan en la interfaz de usuario.  Los items de la Activity aparecen primero, seguidos por los
de cada fragmento en el orden en el que se añade cada fragmento a la Activity.  Si es
necesario, puede volver a ordenar los elementos de menú con el
atributo androide:orderInCategory en cada <item> que necesitemos mover.
Para especificar el menú de opciones para una Activity, hay que sobreescribir el método
onCreateOptionsMenu() (Los fragmentos proporcionan su propio onCreateOptionsMenu()). En
este método, se puede inflar su recurso de menú ( definido en XML ) dentro del menú
proporcionado en la devolución de llamada. Por ejemplo:

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    MenuInflater inflater = getMenuInflater();
    inflater.inflate(R.menu.game_menu, menu);
    return true;
}

También puede añadir elementos de menú utilizando add() y recuperar los elementos con
FindItem().  Puede revisar sus propiedades el MenuItem APIs.
El sistema llama a onCreateOptionsMenu() al iniciar la Activity, con el fin de mostrar los
elementos de la barra de acción.
Manejando los eventos Clic
Cuando el usuario selecciona un elemento del menú de opciones (incluyendo elementos de
acción en la barra de acciones), el sistema llama al método onOptionsItemSelected() de su
activity.  Este método pasa el MenuItem seleccionado.  Puede identificar el item llamando a
getItemID(), que devuelve el identificador único para el elemento del menú (definido por el
atributo android:id en el recurso menú o con un entero dado por el método add()).  Ahora
podemos usar este ID para para realizar la acción apropiada. Por ejemplo:

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    // Handle item selection
    switch (item.getItemId()) {
        case R.id.new_game:
            newGame();
            return true;
        case R.id.help:
            showHelp();
            return true;
        default:
            return super.onOptionsItemSelected(item);
    }
}

Como podemos notar en el código, cuando maneje con éxito un item del menú, debe devolver
true.  Si no ha sido posible controlar el elemento del menú, debe llamar a la implementación
de la superclase onOptionsItemSelected() (esta implementación predeterminada devuelve
false).
Si su Activity incluye fragmentos, el sistema llama primero a onOptionsItemSelected() de la
actividad luego al de cada fragmento (en el orden que se añadió cada fragmento al Activity)
hasta que una devuelva verdadero o todos los fragmentos hallan sido llamados.
A partir de Android 3.0 se añadió la capacidad de definir el comportamiento de hacer clic en
una opción de menú en el mismo archivo XML, utilizando el atributo android:onClick.  El valor
del atributo debe ser el nombre de un método definido en la Activity.  El método debe ser
público y aceptar un único MenuItem parámetro cuando el sistema llama a este método.  Para
obtener más información y un ejemplo, puede ver el recurso de menú.

4.2.2 Menús contextuales


Un menú contextual ofrece acciones que afectan a un item específico o contexto en la interfaz
de usuario.  Puede proporcionar un menú contextual para cualquier View, pero se utilizan con
mayor frecuencia para los elementos de un ListView, GridView , u otras colecciones de Views
en el que el usuario puede realizar acciones directas sobre cada elemento.
Hay dos maneras de proporcionar acciones contextuales:
En un menú contextual flotante.  Un menú aparece como una lista de elementos de menú
flotante (similar a un cuadro de diálogo) cuando el usuario realiza un clic largo (pulsar y
mantener) en un View donde se ha declarado el soporte de un menú contextual.  Los usuarios
pueden realizar una acción contextual sobre un elemento a la vez.
En el action bar contextual.  Este modo es una implementación del sistema de ActionMode
que muestra una barra de acción contextual en la parte superior de la pantalla con los puntos
de acción que afectan el elemento(s) seleccionado.  Cuando este modo está activo, los
usuarios pueden realizar una acción en varios artículos a la vez (si su aplicación lo permite).
El action bar contextual es el más actual y por tanto hoy es la técnica preferida para la
visualización de las acciones contextuales cuando esté disponible.  Aquí el ejemplo de estos
dos tipos:  El de la izquierda es un flotante y el de la derecha es un modo de acción contextual
(action bar contextual).

Dado que hoy la recomendación es usar el modo de acción contextual, veamos cómo se realiza
este.
Para los Views que ofrecen acciones contextuales, por lo general, debe invocar el modo de
acción contextual sobre uno de los dos eventos (o ambos):

 El usuario realiza una clic largo clic en el View.

 El usuario selecciona una casilla de verificación o un componente de interfaz de


usuario similar dentro del View.

Cómo su aplicación invoca el modo acción contextual y define el comportamiento de cada


acción depende de su diseño. Básicamente, hay dos diseños:

 Para las acciones contextuales en, Views arbitrarias individuales.

 Para las acciones de lote contextual en grupos de elementos en un ListView o GridView


(que permite al usuario seleccionar varios elementos y realizar una misma acción para
todos ellos).

Vamos a centrarnos en este último escenario, acciones de lote contextual en grupos de


elementos en un ListView o GridView que son los que más se usan.

Si usted tiene una colección de artículos en un ListView o GridView y desea permitir a los
usuarios realizar acciones por lote, debe:

 Implementar el interfaz  AbsListView.MultiChoiceModeListener y configurarlo para el


ViewGroup con setMultiChoiceModeListener().  En los métodos listener’s de
devolución de llamada, puede especificar las acciones de la barra de acción contextual,
responder los eventos clic y manejar otras devoluciones de llamada heredados del
interfaz ActionMode.Callback.

 Llame setChoiceMode() con el argumento CHOICE_MODE_MULTIPLE_MODAL.

Por ejemplo:

ListView listView = getListView();

listView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL);

listView.setMultiChoiceModeListener(new MultiChoiceModeListener() {

    @Override

    public void onItemCheckedStateChanged(ActionMode mode, int position,

                                          long id, boolean checked) {

        // Here you can do something when items are selected/de-selected,

        // such as update the title in the CAB

    }

    @Override

    public boolean onActionItemClicked(ActionMode mode, MenuItem item) {

        // Respond to clicks on the actions in the CAB


        switch (item.getItemId()) {

            case R.id.menu_delete:

                deleteSelectedItems();

                mode.finish(); // Action picked, so close the CAB

                return true;

            default:

                return false;

        }

    }

    @Override

    public boolean onCreateActionMode(ActionMode mode, Menu menu) {

        // Inflate the menu for the CAB

        MenuInflater inflater = mode.getMenuInflater();

        inflater.inflate(R.menu.context, menu);

        return true;

    }

    @Override

    public void onDestroyActionMode(ActionMode mode) {

        // Here you can make any necessary updates to the activity when

        // the CAB is removed. By default, selected items are deselected/unchecked.

    }

    @Override

    public boolean onPrepareActionMode(ActionMode mode, Menu menu) {

        // Here you can perform updates to the CAB due to

        // an invalidate() request

        return false;

    }

});

Eso es todo.  Ahora, cuando el usuario selecciona un elemento con una clic largo, el sistema
llama al método onCreateActionMode() y muestra la barra de acción contextual con las
acciones especificadas.  Mientras que la barra de acción contextual es visible, los usuarios
pueden seleccionar opciones adicionales.
En algunos casos en los que las acciones contextuales proporcionan puntos de acción
comunes, es posible que desee agregar una casilla de verificación o un elemento de interfaz de
usuario similar que permite a los usuarios seleccionar los elementos, porque no pueden
descubrir el comportamiento de un clic largo.  Cuando un usuario selecciona la casilla de
verificación, puede invocar el modo de acción contextual estableciendo el respectivo elemento
de lista al estado comprobado con setItemChecked().

4.2.3 Menús emergentes


Un PopupMenu es un menú modal anclado a un View.  Aparece debajo de la vista de anclaje si
hay espacio, o por encima de la vista si no lo hay.  Es útil para:

 Proporcionar un menú de estilo de desbordamiento para las acciones que se


relacionan con contenidos específicos (como los encabezados de correo electrónico de
Gmail, que se muestra en la figura).

 Proporcionar una segunda parte de una sentencia de comandos (como un botón


"Añadir" que produce un menú desplegable con diferentes opciones "Añadir").

 Proporcionar un desplegable similar a Spinner que no retenga una selección


persistente.

Si defines tu menú en XML, así es como se puede mostrar el menú emergente:

1.- Instancie un PopupMenu con su constructor, que toma la aplicación actual contexto y la
vista a la que se debe anclar el menú.

2.- Utilice MenuInflater para inflar su recurso de menú en el objeto menú devuelto por
PopupMenu.getMenu().  El nivel de la API de 14 o más, puede utilizar PopupMenu.inflate () en
su lugar.

3.- Llame PopupMenu.show().

Por ejemplo, aquí hay un botón con el atributo android:onClick que muestra un menú
desplegable:

<ImageButton

    android:layout_width="wrap_content"

    android:layout_height="wrap_content"

    android:src="@drawable/ic_overflow_holo_dark"

    android:contentDescription="@string/descr_overflow_button"

    android:onClick="showPopup" />


En el Activity se puede mostrar el menú emergente de esta manera:

public void showPopup(View v) {

    PopupMenu popup = new PopupMenu(this, v);

    MenuInflater inflater = popup.getMenuInflater();

    inflater.inflate(R.menu.actions, popup.getMenu());

    popup.show();

El menú es ocultado cuando el usuario selecciona un elemento o toca fuera del área de menú.
Puede detectar este evento despedir u ocultar el menú utilizando
PopupMenu.OnDismissListener.
Manejando los eventos clic
Para realizar una acción cuando el usuario selecciona un elemento de menú, debe
implementar la interfaz PopupMenu.OnMenuItemClickListener y registrarlo en su PopupMenu
llamando a  setOnMenuItemclickListener().  Cuando el usuario selecciona un elemento, el
sistema llama al onMenuItemClick() de la devolución de llamada de su interfaz.  Por ejemplo,
de esta manera:
 

public void showMenu(View v) {

    PopupMenu popup = new PopupMenu(this, v);

    // This activity implements OnMenuItemClickListener

    popup.setOnMenuItemClickListener(this);

    popup.inflate(R.menu.actions);

    popup.show();

@Override

public boolean onMenuItemClick(MenuItem item) {

    switch (item.getItemId()) {

        case R.id.archive:

            archive(item);

            return true;

        case R.id.delete:

            delete(item);

            return true;

        default:
            return false;

    }

También podría gustarte