Sei sulla pagina 1di 58

http://elbauldeandroid.blogspot.

com/2013/12/fragments
.html

Fragments
Podramos definir a un fragmento como una porcin de interface de usuario o vista que se
integra en una activity. Por lo tanto tendremos la posibilidad de combinar mltiples fragmentos
en una sola actividad o incluso reutilizar fragmentos en otras actividades. De esta manera
cada fragmento tendr su propio ciclo de vida, recibir sus propios eventos de entrada y se
podr agregar o eliminar mientras la activity de acogida este en marcha.

En este articulo vamos a ver como crear fragmentos, agregarlos a una actividad, cambiar
entre fragmentos y como comunicar fragmentos. Al final del articulo tendremos para descargar
el cdigo fuente de una mini aplicacin sobre fragmentos.

Toda la informacin a sido sacada de la pagina de desarrolladores de Android: Fragments.

1. Ciclo de vida




La imagen de la izquierda representa el ciclo de vida de un fragmento. Y la imagen de la
derecha los estados de sus metodos.

Generalmente a la hora de crear un fragmento se deben implementar al menos los siguientes
mtodos:
onCreate() - El sistema llama a este mtodo a la hora de crear el fragmento,
normalmente iniciaremos los componentes esenciales del fragmento.
onCreateView() - El sistema llamara al mtodo cuando sea la hora de crear la interface
de usuario o vista, normalmente se devuelve la view del fragmento.
onPause() - El sistema llamara a este mtodo en el momento que el usuario abandone
el fragmento, por lo tanto es un buen momento para guardar informacin.


2. Crear un fragmento

Para crear un fragmento primero deberemos extender la clase "Fragment" y sobreescribir el
mtodo "onCreateView()" en el que devolveremos la vista de dicho fragmento. Vamos a ver el
ejemplo y lo explicamos a continuacin:

public class FragmentUNO extends Fragment {

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup
container,
Bundle savedInstanceState) {

return inflater.inflate(R.layout.fragment_uno, container,
false);
}

}
Comentar que previamente se a creado el layout para este fragmento y se corresponde con
"fragment_uno.xml".

Al sobreescribir el metodo "onCreateView()" podemos observar que de serie nos da la
posibilidad de utilizar un LayoutInflater, un ViewGroup y un Bundle. El LayoutInflater
normalmente lo utilizaremos para inflar el layout de nuestro fragment. El ViewGroup sera la
vista padre donde se insertara el layout de nuestro fragment. Y por ultimo el Bundle podremos
utilizarlo para recuperar datos de una instancia anterior de nuestro fragment.

El mtodo "inflate()" toma tres parmetros. En el primero indicamos la id del layout de nuestro
fragment. En el segundo indicaremos la view padre de nuestro fragmento. Y por ultimo un
booleano que nos servir para indicar si el inflado del layout debe ser insertado en el
ViewGroup (En este caso es false porque directamente se esta insertando el layout en el
ViewGroup).

De esta manera ya tendremos creado un fragment que nos devolver una vista y que
podremos insertar en cualquier activity de nuestro proyecto.

2.1 SubClases de Fragment

A parte de crear un Fragment directamente, Android nos ofrece la posibilidad de utilizar las
siguientes subclases de Fragment:
DialogFragment - Muestra un cuadro de dialogo flotante.
ListFragment - Muestra una lista de elementos.
PreferenceFragment - Muestra una lista de preferencias.


3. Agregar un Fragment a
una Activity

A la hora de agregar un fragmento a una actividad lo podremos realizar de dos maneras:
1. Declarar el fragmento en el layout de la activity.
2. Agregar directamente el Fragment mediante programacin Android.

3.1 Agregar Fragment mediante layout

Lo primero que tenemos que hacer es crear el layout de nuestra activity especificando un
elemento fragment:

<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">

<fragment

android:name="com.datohosting.fragments.FRAGMENTOS.FragmentUNO"
android:id="@+id/fragment_uno"
android:layout_width="match_parent"
android:layout_height="match_parent"/>

</LinearLayout>
Simplemente creamos el elemento "fragment" y especificamos a travs del atributo
"android:name" la ubicacin de nuestro fragmento (nombre de paquete donde esta ubicado el
fragmento).

Es recomendable crear un identificador nico para cada fragmento que nos puede servir para
restaurar fragmentos o incluso para realizar transacciones o eliminacin de fragmentos. Hay
tres maneras de declarar un identificador:
1. Establecer el atributo "android:id".
2. Establecer el atributo "android:tag"
3. No establecer atributos y el sistema cojera automticamente la id de la vista
contenedora.

Una vez creado el layout de la activity simplemente creamos una actividad y le aplicamos el
metodo "setContentView()" indicando la id del layout que acabamos de crear. El resultado
puede ser el siguiente (en la imagen de ejemplo se han declarado dos elementos fragment en
el layout de la activity):



3.2 Agregar Fragment mediante
programacin

De esta manera podemos agregar un fragment a una activity en cualquier momento.
Simplemente indicaremos la id de una vista padre (ViewGroup) donde deber colocarse el
fragment.

Para ello tenemos que utilizar la API FragmentTransaction y a travs de su mtodo "add()"
aadiremos el fragmento a la vista padre. Despues de aadir el fragment tendremos que
terminar la transaccin a travs del mtodo "commit()".

Vamos a ver el ejemplo y lo explicamos a continuacin:

protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

setContentView(R.layout.mostrar_fragment_dos);

FragmentManager FM = getSupportFragmentManager();
FragmentTransaction FT = FM.beginTransaction();

Fragment fragment = new FragmentUNO();
FT.add(R.id.fragment_container, fragment);
FT.commit();
}
En este caso nuestra activity muestra por defecto un layout "mostrar_fragment_dos.xml" que
contiene un ViewGroup, en este caso en un RelativeLayout que no muestra nada pero nos va
a servir para agregar nuestro fragment en dicha vista padre.

Lo primero que hacemos es crear una instancia de "FragmentManager" a travs de su mtodo
"getSupportFragmentManaget()" (dicho mtodo corresponde a la librera de compatibilidad
v4). De esta manera estamos creando un objeto que nos servir para manejar los fragmentos.

A continuacin creamos una instancia de "FragmentTransaction" para realizar la transaccin
de fragmentos. A travs del mtodo "beginTransaction()" indicamos que vamos a realizar una
transaccin de fragmentos.

Lo siguiente es crear una instancia de nuestro "FragmentUNO" y aadirla a la transaccin a
travs del mtodo "add()" que nos pide como parmetros la id del ViewGroup o vista padre
donde se colocara dicho fragmento (en este caso es la id del RelativeLayout que
comentbamos antes) y como segundo parmetro nos pide la instancia del fragmento que se
mostrara dicha vista.

Para terminar la transaccin siempre deberemos declarar el mtodo "commit()". Y como
resultado podremos ver lo siguiente:



4. Gestionar Fragments

En el punto anterior hemos hablado de transacciones, una transaccin simplemente es una
accin que nos permite agregar, reemplazar, eliminar o incluso realizar otras acciones cuando
trabajamos con fragmentos. Estas transacciones pueden ser apiladas por la activity de
acogida, permitiendo as al usuario navegar entre fragmentos mientras la activity siga en
ejecucin.

Cada transaccin es un conjunto de cambios que se realizan al mismo tiempo. Podremos
realizar dichos cambios a travs de los mtodos "add()", "replace()", "remove()" terminando la
transaccin con el mtodo "commit()".

Para aadir la transaccin a la pila de retroceso de la activity utilizaremos el mtodo
"addToBackStack()" para cada transaccin que realicemos. Esta pila sera administrada por la
activity y permitir al usuario volver a un fragmento anterior pulsando la tecla volver del
smartphone o tablet.

Por otra parte a travs del mtodo "setTransaction()" podemos establecer el tipo de
animacin para cada transaccin.

Para este caso se a creado un ejemplo que muestra un layout con un ViewGroup para mostrar
los fragmentos y un botn que servir para aadir fragmentos a la pila de retroceso.
Empezaremos creando el layout que mostrara la activity:

<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">

<RelativeLayout
android:id="@+id/fragment_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="@+id/boton"
android:layout_below="@+id/texto"/>

<Button
android:id="@+id/boton"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:text="CAMBIA FRAGMENT"/>

</RelativeLayout>
Una vez creado el layout deberemos crear la siguiente activity:

private boolean bol = false;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

setContentView(R.layout.reemplazar_fragments);

final Fragment fragmentUNO = new FragmentUNO();
final Fragment fragmentDOS = new FragmentDOS();

Button boton = (Button) findViewById(R.id.boton);
boton.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
FragmentTransaction FT =
getSupportFragmentManager().beginTransaction();

if (bol) {
FT.replace(R.id.fragment_container, fragmentUNO);
} else {
FT.replace(R.id.fragment_container, fragmentDOS);
}

FT.addToBackStack(null);

FT.commit();

bol = (bol) ? false : true;
}
});
}
Comentar que previamente se han creado dos fragmentos "FragmentUNO" y "FragmentDOS",
cada uno con su layout.

En la activity primero creamos un valor booleano que nos servir para cambiar entre un
fragmento u otro cada vez que el usuario pulse el botn.

Establecemos el layout de la activity y creamos dos instancias de nuestros fragmentos. A
continuacin declaramos nuestro botn y le aplicamos un listener.

Cada vez que el usuario pulse el botn se creara una transaccin aadiendo a la pila un
fragmento u otro a travs del mtodo "addToBackStack()" que pide como parmetro un tag o
identificador para la transaccin que se va a realizar.

Se finaliza la transaccin con el mtodo "commit()" y cambiamos el valor booleano.

El resultado puede ser el siguiente:


Cada vez que el usuario pulse el botn, se creara una nueva transaccin que se ira
acumulando en la pila de retroceso. Simplemente tocando la tecla volver de nuestro
smartphone o tablet iremos retrocediendo los fragments.


5. Comunicar Fragments y
Activities

Para comunicar un fragmento con su activity de acogida podemos utilizar el mtodo
"getActivity()", por lo tanto podremos localizar una vista de la activity de la siguiente manera:

View vista = getActivity().findViewById(R.id.lista);

Por el contrario si queremos comunicar una Activity con un Fragment, deberemos crear una
instancia del fragmento aplicndole uno de los mtodos "findFragmentById()" o
"findFragmentByTag()" de la siguiente manera:

FragUNO fragment = (FragUNO)
getFragmentManager().findFragmentById(R.id.frag_UNO);

5.1 Eventos de llamada

En este punto vamos a ver como podemos pasar valores de un fragmento a otro. Por lo tanto
en algunos casos sera necesario que el fragment comparta eventos con la activity. La manera
ideal es crear una interface en el fragmento y exigir a la activity que la implemente. De esta
manera cuando el fragmento reciba un evento tambin lo har la activity, que se encargara de
recibir los datos de ese evento y compartirlos con otros fragmentos.

Vamos a empezar creando un fragmento "ListFragment" y declararando la interface:

public interface OnArticuloSelectedListener {
public void onArticuloSelected(String str);
}
A esta interface la hemos llamado "onArticuloSelectedListener" y simplemente contiene un
mtodo llamado "onArticuloSelected" con un nico parmetro.

Lo siguiente es sobreescribir el mtodo "onListItemClick" en el mismo fragmento, que se
encargara de enviar el evento y los datos del evento a la interface. De esta manera cada vez
que el fragmento reciba un evento, automticamente lo mandara a la interface que a su vez lo
recibir la activity:

private OnArticuloSelectedListener listener;

@Override
public void onListItemClick(ListView l, View v, int position, long id)
{
listener.onArticuloSelected(valores[position]);
}
Lo primero que necesitamos es una instancia de nuestra interface "listener". Una vez creada
sobreescribimos el mtodo "onListItemClick" y le aplicamos el mtodo de la interface
indicando como argumento los datos que se compartirn por cada evento del usuario.

Para comprobar de que la Activity de acogida implementa la interface vamos a sobreescribir el
mtodo "onAttach()" que sera llamado cada vez que la activity cree una instancia del
fragmento.

@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
try {
listener = (OnArticuloSelectedListener) activity;
} catch (ClassCastException e) {}
}

Para terminar de completar el cdigo de nuestro ListFragment vamos a crear la vista:

private String[] valores = { "Item 1", "Item 2", "Item 3", "Item 4",
"Item 5" };

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setListAdapter(new ArrayAdapter(getActivity(),
android.R.layout.simple_list_item_1, valores));
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_tres, container, false);
}

Simplemente creamos un array string con los valores de la lista. Lo aplicamos en el "onCreate"
y establecemos la vista en el "onCreateView()".


Para terminar deberemos crear la activity e implementar la interface:

.... implements OnArticuloSelectedListener {

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.comunicar_fragments);

FragmentManager FM = getSupportFragmentManager();
FragmentTransaction FT = FM.beginTransaction();

Fragment fragmentTRES = new FragmentTRES();
FT.replace(R.id.fragment_container, fragmentTRES);
FT.commit();
}

public void onArticuloSelected(String str) {
Fragment fragmentCUATRO = new FragmentCUATRO();

Bundle args = new Bundle();
args.putString("str", str);
fragmentCUATRO.setArguments(args);

FragmentManager FM = getSupportFragmentManager();
FragmentTransaction FT = FM.beginTransaction();

transaction.replace(R.id.fragment_container, fragmentCUATRO);
transaction.addToBackStack(null);

transaction.commit();
}
Implementamos la interface del fragment y en el onCreate cargamos su layout agregando el
fragment.

En el mtodo que nos obliga a sobreescribir la interface guardamos los datos que recibimos
de cada evento del fragment en un Bundle y se lo aplicamos a un nuevo fragment. A
continuacin se crea una transaccin a este nuevo fragment y se aade a la pila de retroceso.

Para terminar, el nuevo fragment recuperara los datos de la siguiente manera:

Bundle bundle = getArguments();
String recuperada = bundle.getString("str");

El resultado de todo esto puede ser el siguiente:


Tenemos un Fragmento TRES con una lista, cada vez que el usuario pulse un tem de la lista
se cargara un Fragmento CUATRO mostrando un texto con la opcin elegida.


6. Aadir elementos de
accin

Los fragmentos son capaces de aadir elementos de accin a la ActionBar o en su defecto al
men overflow. Para ello simplemente tendrn que implementar el mtodo
"onCreateOptionsMenu()". Para que este mtodo surja efecto, el fragmento deber llamar en
el onCreate a "setHasOptionsMenu()" indicando como parmetro "true". Todos los elementos
que desee aadir el fragmento se sumaran a los ya existentes.

El resultado de crear un menu.xml e inflarlo en el mtodo onCreateOptionsMenu puede ser el
siguiente:


A parte tambin podremos crear mens contextuales registrando una vista del layout de
nuestro fragment a travs del mtodo "registerForContextMenu()". Para crear el men
contextual utilizaremos el mtodo "onCreateContextMenu()". Y para registrar los eventos de
ese men "onContextItemSelected()".

Si juntamos todo lo anterior podremos crear un men como el de la imagen:



ActionBar y Tabs en Android
Podramos decir que la ActionBar es una barra de herramientas que nos permite ubicar al
usuario en todo momento indicando en que actividad se encuentra (a travs de un titulo y
subtitulo) y a parte nos proporciona un espacio para crear acciones de usuario (ya sean
botones de accin, botn de bsqueda, listas desplegables, tabs, ...)

La API de esta herramienta apareci por primera vez en Android 3.0 (API 11) pero a travs de
la librera de compatibilidad "android-support-v7-appcompact" podemos hacerla compatible a
partir de Android 2.1 (API 7). En esta guia haremos uso de dicha librera para hacer
compatible la ActionBar con el mayor numero de dispositivos posibles.

Para la realizacin de este articulo se ha cogido como base la guia de desarrolladores
Android: ActionBar. Al final de este articulo tendremos la descarga del proyecto con todo lo
incluido en l.

Comentar que tendramos la posibilidad de crear una ActionBar a travs de una librera
externa que prcticamente es una extensin de la librera de compatibilidad que usaremos en
este articulo. Dicha librera se llama ActionBarSherlock y es compatible a partir de Android 2.0
(API 5).

Tabla de contenidos

1. Aadir librera de compatibilidad

2. Utilizar ActionBar en nuestro proyecto
2.1 Aadir elementos de accin
2.2 Manejar clicks en los elementos de accin
2.3 Habilitar el botn volver en la ActionBar
2.4 Dividir ActionBar
2.5 Aadir drop-dwon (spinner)
2.6 Aadir una vista de accin
2.7 Aadir un proveedor de accin
2.8 Crear layout personalizado

3. Crear men de navegacin (Navigation Drawer)
3.1 Habilitar el icono de la ActionBar
3.2 Manejar eventos click del men
3.3 Manejar eventos de apertura y cierre del men

4. Creacin de pestaas (Tabs)
4.1 Crear views deslizantes (ViewPager)
4.2 Crear tabs para ViewPager
4.3 Utilizar view desplazables

5. Aplicar estilo a la ActionBar

6. Cdigo fuente del articulo


1. Aadir librera de
compatibilidad

Primero debemos importar la librera a nuestro workspace siguiendo estos pasos:
1. File/Import/Android/Existing Android Code Into Workspace.
2. Buscamos la librera ubicada en la carpeta /android-
sdk/extras/android/support/v7/appcompact/
3. Seleccionamos la librera y finalizamos.
Con esto ya tenemos la librera cargada en nuestro workspace. Lo siguiente es aadir la
librera a nuestro proyecto siguiendo estos pasos:
1. Seleccionamos nuestro proyecto y entramos en sus Propiedades (hay varias
maneras de hacerlo: desde el men Project, con click derecho encima de nuestro
proyecto o combinando las teclas Alt+Enter).
2. Una vez abierta la nueva ventana pinchamos abajo del todo en Add...
3. Seleccionamos la librera y aceptamos.
Al final debe quedar algo muy similar a esta captura:




2. Utilizar ActionBar en
nuestro proyecto

Para hacer visible la ActionBar en nuestra aplicacin simplemente deberemos editar el
AndroidManifest y establecer un theme del conjunto de temas "Theme.AppCompact".
Podemos hacerlo directamente en <application ...> o en la <activity ...>, todo dependern de
nuestras necesidades.

<application
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/Theme.AppCompat.Light.DarkActionBar">
</application>
<activity
...
...
android:theme="@style/Theme.AppCompat.Light.DarkActionBar">
</activity>

Seguidamente en nuestra actividad tendremos que extender la clase "ActionBarActivity" y con
esto ya podramos ejecutar la aplicacin y tendramos visible la ActionBar en pantalla. Por
defecto pondr como icono el establecido en "android:icon" y como titulo lo establecido en
"android:label".

Para poder trabajar con ella tendremos que crear una instancia del objeto ActionBar.

ActionBar actionBar = getSupportActionBar();

Y ya podramos usar mtodos como los siguientes:

actionBar.hide(); //Ocultar ActionBar
actionBar.setIcon(Drawable); //Establecer icono
actionBar.setTitle(CharSequence); //Establecer titulo
actionBar.setSubtitle(CharSequence); //Establecer Subtitulo


2.1 Aadir elementos de accin

Para crear elementos de accin primero tenemos que crear un recurso del tipo "menu" en el
que indicaremos todos los items o elementos de accin que nos sean necesarios. Este
recuso hay que crearlo dentro de la carpeta /res/menu/

A continuacin vemos un ejemplo que explicaremos seguidamente:

<menu
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:yourapp="http://schemas.android.com/apk/res-auto">

<item
android:id="@+id/buscar" android:title="@string/menu_buscar"
android:icon="@drawable/buscar"
yourapp:showAsAction="ifRoom|withText"/>
<item
android:id="@+id/cortar" android:title="@string/menu_cortar"
android:icon="@drawable/cortar"
yourapp:showAsAction="ifRoom|withText"/>
<item
android:id="@+id/copiar" android:title="@string/menu_copiar"
android:icon="@drawable/copiar"
yourapp:showAsAction="ifRoom|withText"/>
<item
android:id="@+id/eliminar"
android:title="@string/menu_eliminar"
android:icon="@drawable/eliminar"
yourapp:showAsAction="ifRoom|withText"/>
<item
android:id="@+id/compartir"
android:title="@string/menu_compartir"
android:icon="@drawable/compartir"
yourapp:showAsAction="ifRoom|withText"/>

</menu>

Para crear un tem o elemento de accin simplemente utilizaremos los atributos "id" y "title".
Con esto conseguiremos que en nuestra aplicacin nos muestre un men desplegable.

Si lo que queremos es mostrar los elementos de accin como un icono en el ActionBar,
deberemos aadir a la declaracin de nuestro men, la siguiente herramienta:

xmlns:yourapp="http://schemas.android.com/apk/res-auto"
Donde "yourapp" tenemos que sustituirlo por el nombre del paquete de nuestra aplicacin,
ejemplo:

xmlns:com.example.actionbar="http://schemas.android.com/apk/res-
auto"
Una vez hecho esto ya podremos hacer uso del atributo "showasaction" en el que
tendremos que hacer exactamente lo mismo con "yourapp". Este atributo nos permite
controlar de que manera se va a mostrar el elemento de accin. Tiene las siguientes
configuraciones:
1. ifRoom (Mostrara el "icon" en el ActionBar si tiene espacio)
2. always (Mostrara siempre el "icon" en el ActionBar)
3. withText (Se debe usar junto a "ifRoom" o "always" y mostrara el "icon" + "title"
si tiene espacio)
4. never (El tem siempre estar incluido en el men desplegable)
Deberemos tener en cuenta que hacer uso de la conflagracin "always" puede
causar problemas de diseo en dispositivos con pantallas pequeas, por lo que es mas que
recomendable utilizar la configuracin "ifRoom" para que nos gestione el espacio disponible y
muestre automticamente los elementos de accin que entren en ese espacio.

Una vez creado el recurso men con los elementos de accin necesarios deberemos inflar la
vista en nuestra activity a travs del siguiente mtodo:

public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu, menu);
return super.onCreateOptionsMenu(menu);
}

Para la creacin de los iconos podemos visitar esta herramienta de Android Studio: Action Bar
and Tab Icon Generator

El resultado puede ser el siguiente:




2.2 Manejar clicks en los elementos de
accin

Cuando pulsamos un elemento de accin, el sistema hace una llamada al mtodo
"onOptionsItemSelected()". A travs de este mtodo podremos identificar que botn de accin
se a pulsado, simplemente le tendremos que aplicar el mtodo "getItemId()" a su parmetro
"MenuItem" y como resultado tendremos id del tem pulsado. Podemos ver todo esto en un
ejemplo:

public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.buscar:
Toast.makeText(getApplicationContext(), "BUSCAR",
Toast.LENGTH_SHORT).show();
return true;
case R.id.cortar:
Toast.makeText(getApplicationContext(), "CORTAR",
Toast.LENGTH_SHORT).show();
return true;
case R.id.copiar:
Toast.makeText(getApplicationContext(), "COPIAR",
Toast.LENGTH_SHORT).show();
return true;
...
...
...
default:
return super.onOptionsItemSelected(item);
}
}
Lo primero que hacemos es crear un switch para manejar los diferentes botones de accin
que hayamos declarado en nuestro recurso men. Al switch le aplicamos el mtodo
"getItemId()" para conocer la id del botn de accin que ha sido pulsado y para terminar
creamos tantos casos como botones de accin tengamos. En este caso simplemente
mostramos un Toast al pulsar un botn de accin.


2.3 Habilitar el botn volver en la
ActionBar



Android nos permite habilitar el icono de la ActionBar como un botn volver. Para ello tenemos
que seguir dos pasos:
1. Activar el botn volver en la ActionBar a travs del siguiente mtodo:
actionBar.setDisplayHomeAsUpEnabled(true);

2. Indicar a que actividad volver despus de pulsar el botn volver, para ello
tenemos dos posibilidades de hacerlo:
(2.1) Especificar la actividad padre en el AndroidManifest (es la mejor opcin cuando la
actividad padre siempre es la misma, a continuacin se muestra un ejemplo)

<activity
android:name="com.example.actionBar.ActionBarActivity"

android:parentActivityName="com.example.actionBar.MenuPrincipal">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="com.example.actionBar.MenuPrincipal"/>
</activity>
(2.2) Reemplazar los metodos "getSupportParentActivityIntent()" y
"onCreateSupportNavigateUpTaskStack()" en nuestra activity (esta forma es apropiada
cuando la actividad padre puede ser diferente).

2.4 Dividir ActionBar

Android nos ofrece la posibilidad de dividir la ActionBar (Split ActionBar), esto quiere decir que
nuestra aplicacin podr tener un panel superior (ActionBar) y un panel inferior (con los
elementos de accin). Para hacer uso de una ActionBar dividida simplemente deberemos
establecer un atributo para cada activity que lo necesite dentro del AndroidManifest.
1. Aadiendo el atributo "uiOptions" a cada activity conseguiremos una ActionBar
dividida (este mtodo solo es compatible con versiones superiores a un nivel de API
14)
2. Para hacerlo compatible con versiones anteriores de Android tendremos que
agregar un <meta-data> a cada activity
Un ejemplo para hacerlo compatible con la mayora de versiones seria el siguiente:
<activity
android:name="com.example.actionbar.DividirActionBar"
android:uiOptions="splitActionBarWhenNarrow">
<meta-data
android:name="android.support.UI_OPTIONS"
android:value="splitActionBarWhenNarrow" />
</activity>

El resultado puede ser el siguiente:



2.5 Aadir un drop-down (spinner)

Podremos crear una lista deplegable como la que muestra la imagen:


Empezaremos creando un recurso string-array que nos servira para almacenar los items de la
lista desplegable, podemos hacerlo tanto dentro del archivo strings.xml o bien podemos crear
uno nuevo, como nos sea mas cmodo.

<resources>
<string-array name="lista">
<item>Lunes</item>
<item>Martes</item>
<item>Miercoles</item>
<item>Jueves</item>
<item>Viernes</item>
<item>Sabado</item>
<item>Domingo</item>
</string-array>
</resources>

El siguiente paso seria modificar el modo de navegacin de la ActionBar y establecerlo en lista
deplegable. Para ello utilizaremos el siguiente cdigo en el onCreate de nuestra activity:

ActionBar actionBar = getSupportActionBar();
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_LIST);

Una vez hecho esto necesitaremos crear un adaptador "SpinnerAdapter" que utilizaremos
para indicar que items se mostraran en la lista desplegable (el recurso string-array creado
antes) y que diseo tendr dicha lista.

SpinnerAdapter adapter = ArrayAdapter.createFromResource(this,
R.array.lista,
android.R.layout.simple_spinner_dropdown_item);

Para terminar implementamos la interface "ActionBar.OnNavigationListener" que nos servir
para manejar los eventos del usuario al pulsar un tem de la lista desplegable. Vamos a dividir
este paso en tres:
1. Implementar interface "ActionBar.OnNavigationListener"
2. Aplicar interface a nuestro objeto ActionBar a traves del metodo
"setListNavigationCallbacks()"
3. Sobreescribir el mtodo obligado de esta interface
"onNavigationItemSelected()"
// Implementar interface
... implements ActionBar.OnNavigationListener { ...}
// Aplicar interface a nuestro ActionBar (dentro del onCreate)
actionBar.setListNavigationCallbacks(adapter, this);
// Sobreescribir metodo
public boolean onNavigationItemSelected(int arg0, long arg1) {
switch (arg0) {
case 0:
// Opcion seleccionada Lunes
break;
case 1:
// Opcion seleccionada Martes
break;
...
...
}
return false;
}


2.6 Aadir una vista de accin

Una vista de accin es simplemente un widget que aparece en nuestro ActionBar como un
elemento de accin. Cada vez que pulsemos ese elemento de accin nuestro ActionBar se
transformara ofreciendo un acceso rpido a otras opciones sin tener que cambiar de activity,
fragment o ActionBar. Uno de los mas conocidos es la barra de bsqueda que aparece en
unas cuantas aplicaciones, al pulsar sobre el icono de la lupa se nos abre automticamente un
edittext:




Lo primero que tenemos que hacer para crear una vista de accin es generar un recurso
"menu" indicando el atributo "actionLayout" o "actionViewClass". De esta manera crearemos
un recurso de diseo o una clase widget respectivamente. Vamos a ver como crear el recurso
para el "SearchView" de la imagen de arriba:

<menu
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:com.example.actionbar="http://schemas.android.com/apk/res-
auto" >

<item
android:id="@+id/buscar"
android:title="@string/menu_buscar"
android:icon="@drawable/ic_action_search"
com.example.actionbar:showAsAction="ifRoom|collapseActionView"

com.example.actionbar:actionViewClass="android.support.v7.widget.Searc
hView"/>

</menu>
Cosas a tener en cuenta, primero acordaros de cambiar el nombre de paquete y poner el de
vuestra aplicacin (sustituir "com.example.actionbar").
En el atributo showAsAction estamos indicando "collapseActionView" para establecer que el
tem tiene que aparecer en la aplicacin como un elemento de accin (imagen 1).
Y por ultimo en el atributo actionViewClass establecemos la clase widget del SearchView a
travs de la librera de soporte v7.

Solo nos quedara configurar el mtodo onCreateOptionsMenu para hacer funcional esta vista
de accin. Voy a explicar como hacerlo y a parte le vamos a aplicar dos listeners. Uno para
cuando se expanda y se cierre el elemento de accin y otro para cuando el usuario introduzca
un texto y lo acepte. Por lo tanto pongo el cdigo y luego lo explico un poco:

public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.vistabusqueda, menu);

MenuItem searchItem = menu.findItem(R.id.buscar);

SearchView searchView = (SearchView)
MenuItemCompat.getActionView(searchItem);

// LISTENER PARA EL EDIT TEXT
searchView.setOnQueryTextListener(this);
// LISTENER PARA LA APERTURA Y CIERRE DEL WIDGET
MenuItemCompat.setOnActionExpandListener(searchItem, this);

return super.onCreateOptionsMenu(menu);
}
Lo primero que hacemos es inflar la vista creada anteriormente a travs del mtodo
getMenuInflater().
Seguidamente creamos un objeto MenuItem correspondiente al tem creado en el recurso
men. Este sera el elemento de accin que veremos en el ActionBar.
Seguimos creando otro objeto SearchView al que le aplicaremos la vista del elemento de
accion que hemos creado antes, para ello utilizamos el mtodo getActionView(). De esta
manera estamos convirtiendo el elemento de accin en una vista de accin. Si ejecutamos el
cdigo en este punto obtendremos como resultado lo que se ve en las imgenes de arriba.

Para configurar los listener debemos implementar las interfaces "OnQueryTextListener" y
"OnActionExpandListener". Una vez hecho esto ya podemos aplicar los listeners a los dos
objetos creados en el "onCreateOptionsMenu" (las dos siguientes lineas de cdigo).

Al implementas estas dos interfaces estamos obligados a sobreescribir los siguientes
mtodos:

public boolean onQueryTextChange(String arg0) {
return false;
}
public boolean onQueryTextSubmit(String arg0) {
return false;
}
public boolean onMenuItemActionCollapse(MenuItem arg0) {
return true;
}
public boolean onMenuItemActionExpand(MenuItem arg0) {
return true;
}
Los dos primeros mtodos corresponden a la interface "OnQueryTextListener". Con el primero
podemos trabajar en el momento que el usuario pincha el elemento de accin y se expande el
edittext capturando todo lo que haga. Con el segundo mtodo podremos trabajar cuando el
usuario acepte una bsqueda.

Y para terminar los dos siguientes mtodos corresponden a la interface
"OnActionExpandListener". El primero lo usaremos para cuando el elemento de accin se
cierre. Y el segundo mtodo para cuando el elemento de accin se expanda.


2.7 Aadir un proveedor de accin

Es muy similar al ejemplo anterior (vista de accin) pero en este caso un "action provider" o
proveedor de accin reemplazara a un elemento de accin con un diseo personalizado. Esto
quiere decir que un proveedor de accin tiene todo el control del elemento de accin y es
capaz de mostrar un submenu al pulsar el botn de accin entre otras cosas.

Tenemos la posibilidad de crear nuestro propio proveedor de accin utilizando la clase
"ActionProvider" aunque Android por defecto nos ofrece la posibilidad de crear alguno como el
"ShareActionProvider" que seria el botn de compartir que aparece en alguna que otra
aplicacion, el de la imagen:


En este caso tenia preparado crear lo que se ve en la imagen que es lo que incluye el cdigo
fuente del final del articulo pero he decidido crear un ActionProvider personalizado y hacer
algo similar al ejemplo anterior (vista de accin) para ver el resultado mas rpidamente y tener
una base de esto.

La documentacin Android nos dice que tenemos que crear nosotros mismos nuestro
ActionProvider, por lo tanto empezaremos creando una clase que extienda de ActionProvider:

public class BusquedaAP extends ActionProvider{

Context context;

public BusquedaAP(Context context) {
super(context);
this.context = context;
}

public View onCreateActionView() {
LayoutInflater layoutInflater = LayoutInflater.from(context);
View view = layoutInflater.inflate(R.layout.ap_busqueda,
null);
return view;
}
}

Despus necesitaremos crear el layout que estamos inflando en el mtodo
"onCreateActionView":

<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="match_parent"
android:orientation="horizontal" >

<EditText
android:id="@+id/edit"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:inputType="text"/>

</RelativeLayout>

Continuamos creando un recurso men que har referencia a nuestra clase "BusquedaAP" a
travs del atributo actionProviderClass:

<menu
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:com.example.actionbar="http://schemas.android.com/apk/res-
auto">

<item
android:id="@+id/buscar"
android:title="@string/menu_buscar"
android:icon="@drawable/ic_action_search"

com.com.example.actionbar:showAsAction="always|collapseActionView"

com.com.example.actionbar:actionProviderClass="com.example.actionbar.B
usquedaAP"/>

</menu>
Recordar cambiar el nombre del paquete y la clase en el atributo "actionProviderClass" para
hacer referencia a la clase que hayamos extendido de ActionProvider.

Por ultimo solo nos queda configurar el cdigo Android, para ello inflaremos el men que
acabamos de crear en el mtodo "onCreateOptionsMenu()":

public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.busqueda_ap, menu);
return super.onCreateOptionsMenu(menu);
}

El resultado sera el siguiente:




Es un ejemplo muy rpido de las posibilidades que ofrece utilizar un proveedor de accin o
ActionProvider. El tema es un poco mas extenso al utilizar la clase ActionProvider porlo que
es mas que recomendable echarle un ojo en google. Pero la idea es esa, adaptar un botn de
accin a lo que nosotros queramos.


2.8 Crear layout personalizado

Otra opcin que nos ofrece Android es la posibilidad de aplicar un layout personalizado a la
ActionBar, de esta manera se nos abre otro abanico de posibilidades.

El primer paso seria crear un layout con la disposicin que necesitemos de la ActionBar.

Una vez creado el layout nos vamos a nuestra activity y simplemente tendramos que poner el
modo de navegacin de la ActionBar en custom y aplicarle el nuevo layout, metiendo el
siguiente cdigo en el onCreate podramos realizarlo:
ActionBar actionBar = getSupportActionBar();
actionBar.setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM);
actionBar.setCustomView(R.layout.actionbar_top);
A parte de introducir este cdigo en el onCreate tendriamos que configurar los botones, textos,
imagenes que hayamos metido en el layout personalizado.

Pero el resultado puede ser algo similar a esto:



3. Crear men de
navegacin



Este tipo de men se llama "Navigation Drawer" y es un panel oculto que esta ubicado en el
borde izquierdo de la pantalla. Se puede hacer visible de dos maneras, o bien haciendo un
gesto desde la izquierda de la pantalla o pulsando directamente el icono de la ActionBar.

Para aadir el men de navegacin a nuestra aplicacin tenemos que hacer uso de la API
"DrawerLayout" disponible en la librera de compatibilidad v4.

Primero deberemos crear el layout del DrawerLayout:

<android.support.v4.widget.DrawerLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<FrameLayout
android:id="@+id/content_frame"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<ListView
android:id="@+id/left_drawer"
android:layout_width="240dp"
android:layout_height="match_parent"
android:layout_gravity="start"
android:choiceMode="singleChoice"
android:background="#111"/>
</android.support.v4.widget.DrawerLayout>
Al hacer uso de DrawerLayout, deberemos especificar 2 tipos de vista:
1. Una vista principal que sera la mostrada por la activity (en este caso es un
FrameLayout)
2. Otra vista para el men de navegacin (en este caso un simple listview)

En la segunda vista (listview) deberemos indicar su gravedad (normalmente "start") y su
anchura (no debe sobrepasar los 320dp).

Una vez creada la vista del Navigation Drawer ya podemos pasar a nuestra actividad para
trabajar con ella. Primero extenderemos la clase "ActionBarActivity" y con el siguiente cdigo
crearamos nuestra actividad con su Navigation Drawer:

public class CrearCajon extends ActionBarActivity {

private DrawerLayout cajon;

protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.cajon);

String[] valores =
getResources().getStringArray(R.array.cajon);
cajon = (DrawerLayout) findViewById(R.id.drawer_layout);
ListView opciones = (ListView) findViewById(R.id.left_drawer);
opciones.setAdapter(new ArrayAdapter(this,
R.layout.plantilla_cajon, valores));
}
}
Primero establecemos la vista creada anteriormente a travs del mtodo setContentView().
Creamos un array String que usaremos para aplicar al ListView (sern todas las opciones de
nuestro Navigation Drawer)
Continuamos creando un objeto ListView.
Y aplicamos un adaptador para ese ListView

Con esto ya podramos visualizar la actividad con su men de navegacin. Lo nico que para
acceder al men solo podramos hacerlo dibujando el gesto desde el lado izquierdo. Vamos a
continuar y a ver como podramos habilitar el icono de la aplicacin para acceder a este men.


3.1 Habilitar el icono de la ActionBar

Lo primero que tenemos que hacer es crear un objeto de la clase "ActionBarDrawerToggle" y
habilitar el icono de la aplicacin como botn. Por lo tanto empezaremos aadiendo el
siguiente cdigo al OnCreate anterior:

// CREAMOS EL OBJETO FUERA DEL ONCREATE
private ActionBarDrawerToggle toggle;

// ESTO DENTRO DEL ONCREATE
toggle = new ActionBarDrawerToggle(this, cajon,
R.drawable.ic_drawer,
R.string.drawer_open,
R.string.drawer_close);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setHomeButtonEnabled(true);
El constructor del objeto "toggle" nos pide como parmetros la actividad que aloja el men de
navegacion (this), el DrawerLayout (cajon), un icono drawable y dos palabras que describirn
la apertura y cierre del cajn (para la accesibilidad).

Para terminar de habilitar el icono de la aplicacin deberemos sobreescribir los siguientes
mtodos en nuestra activity:

protected void onPostCreate(Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState);
toggle.syncState();
}

public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
toggle.onConfigurationChanged(newConfig);
}

public boolean onOptionsItemSelected(MenuItem item) {
if (toggle.onOptionsItemSelected(item)) {
return true;
}
return super.onOptionsItemSelected(item);
}
El primero mtodo sera llamado una vez que la actividad haya sido creada (justo despus del
onStart y onRestoreInstanceState). En el simplemente le aplicamos el mtodo "syncState()" al
objeto "toggle" para sincronizar el estado del icono de la aplicacin con nuestro DrawerLayout.

El segundo mtodo sera llamado cuando haya cambios en la configuracin del sistema. Por lo
tanto aplicaremos la nueva configuracin a nuestro objeto "toggle" a travs del mtodo
"onConfigurationChanged()".

Y el ultimo mtodo no es realmente necesario pero nos puede servir para manejar los clicks
en nuestro men de navegacin. Este sera llamado cuando tenga lugar un click en nuestro
men. En el simplemente indicamos que si se a pulsado una opcin del men devuelva true.
Tendramos la posibilidad de manejar los clicks en nuestro men a travs del parmetro
MenuItem de dicho mtodo.


El resultado despus de crear todo lo anterior es el siguiente:



3.2 Manejar eventos click del men

Podramos hacerlo de dos maneras o bien utilizando el mtodo anterior
(onOptionsItemSelected) o implementando la interface "ListView.OnItemClickListener". En
este caso usaremos la segunda opcin.

Empezamos implementando la interface y se la aplicamos a nuestro listview aadiendo esto al
cdigo que vamos creando en nuestra actividad:

opciones.setOnItemClickListener(this);
Esta interface que estamos implementando nos obliga a sobreescribir el mtodo
"onItemClick()":

public void onItemClick(AdapterView arg0, View arg1, int arg2, long
arg3) {
switch (arg2) {
case 0:
Toast.makeText(getApplicationContext(), "BUSCAR",
Toast.LENGTH_SHORT).show();
break;
case 1:
Toast.makeText(getApplicationContext(), "CORTAR",
Toast.LENGTH_SHORT).show();
break;
...
...
...
}
cajon.closeDrawer(opciones);
}
Para conocer la posicin del tem que se a pulsado del men utilizaremos el parmetro "arg2"
y creamos un switch para manejar todas las opciones de nuestro men de navegacin.
Deberemos acordarnos de cerrar el men de navegacin con el mtodo "closeDrawer()"
indicando la vista a cerrar, en nuestro caso es el listview.


3.3 Manejar eventos de apertura y cierre
del men

Android tambin nos ofrece la posibilidad de manejar estos eventos y controlar en cada
momento que hacer cuando se abre o se cierra el men de negacin.

En este caso vamos a implementar la interface "DrawerListener" y se la aplicamos a nuestro
objeto DrawerLayout:

cajon.setDrawerListener(this);
Esta interface que estamos implementando nos obliga a sobreescribir los siguientes mtodos:

public void onDrawerClosed(View arg0) {
actionBar.setTitle("EJ ActionBar");
}

public void onDrawerOpened(View arg0) {
actionBar.setTitle("Menu Principal");
}

public void onDrawerSlide(View arg0, float arg1) {}

public void onDrawerStateChanged(int arg0) {}
El primer mtodo y el segundo son llamados cuando el men de navegacin es abierto o
cerrado. En este caso simplemente modificamos el titulo de la ActionBar.

El tercer mtodo es llamado cuando cambia la posicin del men de navegacin. Como
parmetros tenemos la vista hija que a sido movida.

Y el cuarto y ultimo mtodo es llamado cuando hay un cambio de estado de movimiento en el
men de navegacion. Como parmetro tenemos el nuevo estado de movimiento del men.
Este nuevo estado puede ser (STATE_IDLE, STATE,DRAGGING, STATE_SETTLING).


4. Creacion de pestaas
(Tabs)

Crear pestaas o tabs en nuestra aplicacin puede ser una buena practica de cara al usuario,
le ayudara a explorar nuestra aplicacin y le sera fcil cambiar entre las diferentes vistas
rpidamente. Comentar que cuando el tamao de pantalla es lo suficientemente grande
(normalmente pantalla en modo landscape o tablets) estas pestaas aparecen dentro de la
ActionBar junto a los elementos de accin. Por otro lado cuando el tamao de pantalla es
reducido (smartphones con pantalla pequea) estas pestaas suelen aparecer en barra
separada justo debajo de la ActionBar.




A continuacin vamos a ver como crear tabs de una manera muy sencilla. Lo primero que nos
dice la documentacin Android es que tenemos que implementar la interface
"ActionBar.TabListener" por lo tanto crearemos la siguiente clase para ello:

public class TabsListener <T extends Fragment> implements TabListener
{

private Fragment fragment;
private final String tag;

public TabsListener(Activity activity, String tag, Class<T> cls) {
this.tag = tag;
fragment = Fragment.instantiate(activity, cls.getName());
}

public void onTabSelected(Tab tab, FragmentTransaction ft) {
ft.replace(android.R.id.content, fragment, tag);
}

public void onTabUnselected(Tab tab, FragmentTransaction ft) {
ft.remove(fragment);
}

public void onTabReselected(Tab tab, FragmentTransaction ft) {}

}
Esta clase sera la encargada de manejar los eventos que tengan lugar en las pestaas o tabs.
Al implementar la interface "ActionBar.TabListener" debemos sobreescribir los mtodos
"onTabSelected()", "onTabUnselected()" y "onTabReselected()" que practicamente el nombre
lo dice todo.

En este caso cuando se seleccione una pestaa simplemente reemplazamos el fragmento y
establecemos la view de ese fragmento. Para las pestaas que no estn seleccionadas
simplemente eliminamos ese fragmento y por lo tanto su view. De esta manera lo que estamos
haciendo es que se cargue la view de un fragmento cada vez que pulsamos una pestaa y
para las pestaas no seleccionadas se elimine la view de cada fragmento. No es la manera
mas practica pero es un buen comienzo.

Lo siguiente que tenemos que hacer es crear los fragmentos, por cada pestaa que queramos
incluir en la aplicacin tendremos que crear un fragmento. En este caso solo voy a exponer
como se crea un fragmento pero en la aplicacin del final del articulo lo veres con tres. Por lo
tanto vamos a crear una nueva clase que extienda de "Fragment":

public class Fragment_Productos extends Fragment {

public View onCreateView(LayoutInflater inflater,
ViewGroup container, Bundle savedInstanceState) {

View rootView = inflater.inflate(R.layout.fm_productos,
container, false);

TextView texto = (TextView)
rootView.findViewById(R.id.texto_productos);

texto.setText("Tab seleccionada" + "\n\n" + "Productos");;

return rootView;
}

}
Esta clase tambin es muy simple, os recomiendo echarle un ojo a los fragmentos porque
tiene bastantes mas posibilidades de las que se exponen aqu. En este caso hemos creado
previamente un layout "fm_productos" en el que simplemente ponemos un texto en medio de
la view.

Una vez creado el layout pasamos a la clase "Fragment_Productos" que extendemos de
"Fragment". Dentro de la clase simplemente sobreescribimos el mtodo "onCreateView()" que
sera el encargado de crear la vista cada vez que pulsemos en una pestaa. Dentro del mtodo
simplemente inflamos el layout creado previamente, configuramos el texto y establecemos un
nuevo texto.

Recordar que tendramos que repetir este paso por cada pestaa que creemos para nuestra
aplicacin. Ya por ultimo solo nos queda crear nuestra activity, dejo el cdigo y lo explicamos
debajo:

public class CrearTabs extends ActionBarActivity {

protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

ActionBar actionBar = getSupportActionBar();

actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);

/**CREAR TABS**/
Tab tab = actionBar.newTab()
.setText(R.string.productos)
.setTabListener(new TabsListener(
this, "productos", Fragment_Productos.class));
actionBar.addTab(tab);

....
....
....

}
}
Al crear nuestra activity extendemos la clase "ActionBarActivity" y sobreescribimos el mtodo
"onCreate()". Dentro del mtodo creamos el objeto ActionBar y ponemos el modo de
navegacin de la ActionBar en modo pestaas o tabs.

Y ya para terminar tendramos que crear tantas pestaas como fragmentos hayamos creado.
Para crear una nueva pestaa utilizamos el mtodo "newTab()" al que le indicamos el texto a
mostrar en la pestaa a traves del metodo "setText()". Tambin podramos indicarle un icono a
mostrar a travs del mtodo "setIcon()" pero no es el caso. Seguimos creando el listener para
esa pestaa, aqu es donde entra la clase creada al principio de este punto. Por lo tanto
creamos el listener para esa pestaa a travs del mtodo "setTabListener()" y le aplicamos un
nuevo TabsListener indicando los parmetros del constructor de esta clase, (una activity, un
tag o identificador, y la clase o fragmento). Para concluir tendremos que aadir la nueva
pestaa creada a la actionbar a travs del mtodo "addTab()".

Si todo nos a salido bien como resultado podremos obtener algo parecido a esto:




Como se comentaba al principio de este punto, dependiendo de si tiene espacio se mostraran
las pestaas en nuevo panel (imagen superior) o incluidas en el ActionBar (imagen inferior).

4.1 Crear views deslizantes

Quizs no sea el termino mas correcto pero mas o menos se entiende, realmente se le llama
paginacin horizontal. El caso es que la idea es poder cambiar de vista deslizando el dedo de
un lado a otro. La documentacin Android nos dice que para crear este tipo de vista tenemos
que utilizar un "ViewPager" disponible a travs de la librera de compativilidad v4.

As que empezamos creando este layout:

<android.support.v4.view.ViewPager
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/pager"
android:layout_width="match_parent"
android:layout_height="match_parent" />

El siguiente paso es crear las vistas que incluir ese ViewPager. Para ello es necesario utilizar
un "PagerAdapter" y Android nos ofrece dos posibilidades:
1. FragmentPagerAdapter: es la clase mas indicada para crear un numero
determinado de vistas
2. FragmentStatePagerAdapter: clase mas indicada para cuando tenemos un
numero indeterminado de vistas, automticamente Android ira destruyendo fragmentos
que no estn a la vista reduciendo el consumo de memoria.
En este caso vamos a partir del ejemplo anterior y vamos a adaptar los mismos fragmentos.
Por lo tanto vamos a crear una clase que extienda de "FragmentPagerAdapter" estableciendo
un numero determinado de tres vistas (en la aplicacin del final de articulo podris observarlo).
public class PagerAdapter extends FragmentPagerAdapter {

public PagerAdapter(FragmentManager fm) {
super(fm);
}

public Fragment getItem(int arg0) {
switch (arg0) {
case 0:
return new Fragment_Productos();
case 1:
return new Fragment_Clientes();
case 2:
return new Fragment_Pedidos();
default:
return null;
}
}

public int getCount() {
return 3;
}

}
Creamos nuestro adaptador y al extender "FragmentPagerAdapter" nos obliga a crear un
constructor (que en este caso no lo usaremos, por lo tanto lo dejamos tal cual), y deberemos
sobreescribir los mtodos "getItem()" y "getCount". Con el primer mtodo le estamos indicando
que cuando tenga que cargar dicha vista nos cree un nuevo fragmento. Y con el segundo
mtodo simplemente le devolvemos el numero de vistas.

De esta manera siempre tendr cargado en memoria el fragmento o pestaa que este visible
en pantalla y tambin el mas cercano a la derecha e izquierda, el resto de pestaas o
fragmento no existirn hasta que no nos acerquemos a ellos.

Para terminar tendremos que configurar el onCreate de nuestra activity principal por lo tanto
pongo el cdigo y luego lo explico un poco:

public class CrearTabsSwipe extends FragmentActivity {

protected void onCreate(Bundle arg0) {
super.onCreate(arg0);
setContentView(R.layout.tabs_swipe);

PagerAdapter adapter = new
PagerAdapter(getSupportFragmentManager());
ViewPager mViewPager = (ViewPager) findViewById(R.id.pager);
mViewPager.setAdapter(adapter);
}
Aqu simplemente establecemos el layout creado previamente a travs del mtodo
"setcontentView()". Y creamos un objeto de nuestra clase (PagerAdapter) que utilizaremos
como adaptador de las vistas. Ya por ultimo configuramos el "ViewPager" de nuestro layout y
le aplicamos el adaptador.

El resultado sern estas tres vistas, conforme deslicemos el dedo veremos una u otra y
siempre tendr cargada en la memoria la vista mas cercana a la que se vea en pantalla:



Comentar un par de cosas, la ActionBar es visible porque hemos configurado el botn volver a
travs del AndroidManifest. Y las tabs o pestaas no estn presentes porque simplemente
hemos creado una paginacin horizontal. En el siguiente punto vamos a ver como aadir las
tabs para estas vistas.

4.2 Crear tabs para ViewPager

En este punto vamos a partir del ejemplo anterior donde habamos creado tres vistas. Vamos
a crear una tab o pestaa por cada vista que al pulsarla nos mostrara la vista de esa pestaa.
A parte tambin tendr implementado el sistema de paginacin horizontal, cada vez que
deslicemos a un lado o a otro nos mostrara una vista y cambiara automaticamente la pestaa.

Para empezar tenemos que modificar nuestra activity e implementar alguna cosilla mas, la
dejo y se explica abajo:

public class CrearTabsSwipe extends ActionBarActivity implements
ActionBar.TabListener,
OnPageChangeListener {

private ViewPager mViewPager;;

protected void onCreate(Bundle arg0) {
super.onCreate(arg0);
setContentView(R.layout.tabs_swipe);

PagerAdapter adapter = new
PagerAdapter(getSupportFragmentManager());
mViewPager = (ViewPager) findViewById(R.id.pager);
mViewPager.setAdapter(adapter);

mViewPager.setOnPageChangeListener(this);

ActionBar actionBar = getSupportActionBar();
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);

Tab tab =
actionBar.newTab().setText(R.string.productos).setTabListener(this);
actionBar.addTab(tab);

...
...
...
}
}
Primeramente empezamos cambiando la extensin de la clase por "ActionBarActivity" para
poder hacer uso de las tabs. Implementamos las dos interfaces "ActionBar.TabListener" y
"OnPageChangeListener" que mas abajo explicare sus mtodos obligados.

El cdigo es practicamente le mismo hasta el metodo "setOnPageChangeListener()" que le
aplicamos a nuestro ViewPager. Y los pasos siguientes tambin se han visto anteriormente.
Se crea el objeto actionBar para ponerlo en modo tabs y creamos las tres pestaas
aplicndoles el listener a travs del "this"

Ahora vamos con las intefaces muy sencillas tambin, primero con "ActionBar.TabListener":

public void onTabSelected(Tab arg0, FragmentTransaction arg1) {
mViewPager.setCurrentItem(arg0.getPosition());
}

public void onTabReselected(Tab arg0, FragmentTransaction arg1) {}

public void onTabUnselected(Tab arg0, FragmentTransaction arg1) {}
Esta interface la hemos visto antes as que simplemente dir que utilizamos el mtodo
"setTabSelected()" para que cuando el usuario pinche en una tab o pestaa nuestro
ViewPager cambie automaticamente de vista.

La siguiente interface es "OnPageChangeListener":

public void onPageSelected(int arg0) {
getSupportActionBar().setSelectedNavigationItem(arg0);
}

public void onPageScrollStateChanged(int arg0) {}

public void onPageScrolled(int arg0, float arg1, int arg2) {}
Esta interface tambin utiliza tres mtodos y en este caso solo haremos uso del primero que
se utiliza cuando una vista se muestra en pantalla al deslizar de un lado a otro. Nosotros
dentro del mtodo le estamos diciendo que cambie de tab y ponga la correspondiente.

El siguiente mtodo "onPageScrollStateChanged" se utiliza para controlar el estado de
desplazamiento, es decir, podramos controlar el puntero del usuario al cambiar de vistas y
preguntar cuando empieza a deslizar, cuando esta deslizando y cuando a terminado de
deslizar una vista.

Y el ultimo mtodo "onPageScrolled" lo podremos utilizar para controlar cuando una vista se
esta desplazando.

El resultado sera el mismo del punto anterior pero en este caso tendremos pestaas que
cambian segn el usuario deslice la vista de un lado a otro e incluso el usuario podr
seleccionar las pestaas y se mostrara su contenido automaticamente. La imagen muestra el
resultado:



4.3 Utilizar view desplazable

En este punto vamos a ver como crear lo que muestra la siguiente imagen:


En este caso en vez de utilizar pestaas, simplemente es una barra de informacin donde le
indicara al usuario en que vista esta ubicado. Esta barra de informacin se ira deslizando
conforme el usuario vaya deslizando las vistas o fragmentos.

Primero tendremos que crear el layout, es muy similar al del punto anterior:

<android.support.v4.view.ViewPager
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/pager"
android:layout_width="match_parent"
android:layout_height="match_parent" >

<android.support.v4.view.PagerTitleStrip
android:id="@+id/pager_title_strip"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="top"
android:background="#33b5e5"
android:textColor="#000"
android:paddingTop="4dp"
android:paddingBottom="4dp" />

</android.support.v4.view.ViewPager>
Seguimos utilizando la clase "ViewPager" pero en este caso le aadimos un "PagerTitleStrip"
que nos servir para establecer la vista de la imagen de arriba. Podemos controlar su
gravedad a travs del atributo "layout_gravity" para ponerlo en el top (arriba) o en el bottom
(abajo).

El siguiente paso es crear un adaptador y vamos a coger el del punto 4.1 (PageAdapter y le
vamos a aadir el siguiente cdigo, dentro de su clase como si fuera otro mtodo mas de la
clase:

public CharSequence getPageTitle(int position) {
String titulo = null;
switch (position) {
case 0:
titulo = "PRODUCTOS";
break;
case 1:
titulo = "CLIENTES";
break;
case 2:
titulo = "PEDIDOS";
break;
}
return titulo;
}
Este mtodo sera el encargado de poner el titulo en el nuevo panel informativo que estamos
creando. Comentar que seguimos utilizando los tres fragmentos de siempre (en el cdigo
fuente lo viereis claro).

Para terminar crearemos nuestra activity que viene siendo la misma que hemos creado en los
puntos anteriores:

public class CrearTabsSwipe2 extends ActionBarActivity {

protected void onCreate(Bundle arg0) {
super.onCreate(arg0);
setContentView(R.layout.tabs_swipe_dos);

PagerAdapter adapter = new
PagerAdapter(getSupportFragmentManager());
ViewPager mViewPager = (ViewPager) findViewById(R.id.pager);
mViewPager.setAdapter(adapter);
}
}


5. Aplicar estilo a la
ActionBar

Una buena manera de crear los recursos de iconos para nuestra ActionBar (ya sea para
elementos de accion o tabs) es utilizar la herramienta: ActionBar and Tab Icon Generator

Tambin podemos crear los recursos del icono del men de navegacin o Navigation Drawer
a travs de la siguiente herramienta: Navigation Drawer Indicator Generator

Y para terminar recomiendo crear un tema para nuestra ActionBar a travs de la
herramienta: ActionBar Style Generator. Indicando en "Style compatibility" que sea un tema
para "AppCompact", de esta manera conseguiremos que sea compatible con versiones
anteriores de Android.

Una vez creado el tema para nuestra ActionBar tendremos que descomprimir e incluir todas
las carpetas en nuestro proyecto. Teniendo esa base podremos modificar cualquier cosa a
nuestro gusto a parte de aprender como se modifica cada cosa de la ActionBar.

Un ejemplo de lo que podramos hacer con esto es el siguiente:




6. Cdigo fuente del
articulo

Aqu os dejo practicamente todo lo que se a visto en el articulo en forma de aplicacin un poco
simple, pero con esta base aprenderemos a manejar bastante bien la ActionBar +Tabs y sus
posibilidades.

DESCARGAR: EJEMPLO ACTION BAR & TABS

Potrebbero piacerti anche