Android/ViewPager i Tabbed ActionBar
ViewPager
modificaQuè és
modificaUn ViewPager és un element d'interfície gràfica d'Android que permet a l'usuari navegar entre els diferents elements d'una llista lliscant (swipe) amb el dit, passant d'una pàgina a una altra.
Partim inicialment del punt on tenim una activitat que mostra un llistat d'elements. En clicar sobre un dels elements volem que s'iniciï una nova activitat (o fragment) que mostri en detall l'element triat a la llista. Per a passar a veure un altre element de la llista amb detall, haurem de tirar endarrere i llavors triar el nou element. El ViewPager ve a solucionar parcialment aquesta molèstia permetent avançar endavant o endarrere un element de la llista sense sortir de la vista detallada.
Estructura
modificaPer a la implementació del ViewPager hem d'afegir un pas intermedi entre la tria de l'element de la llista i la seva visualització detallada. A partir d'aquest moment haurem de treballar amb Fragments a la part del controlador: concretament la vista detallada de l'element serà creada dins d'un fragment i no pas dins d'una activity. A continuació el fragment penjarà d'una activitat pare que és qui implementa el ViewPager; o millor dit, el viewPager serà qui carregarà el fragment amb les dades de l'element pertinent sense la necessitat de recrear cap activity.
Implementació
modificaLa implementació la farem amb un exemple d'una aplicació que visualitza un llistat de notes i que permet veure cadascuna d'elles detalladament.
En primer lloc afegirem la biblioteca de suport a les dependències de l'aplicació. (A data d'Octubre de 2016 l'objecte ViewPager només es troba disponible a la llibreria de suport d'Android i no es troba a les darreres versions del SDK).
- Link al repositori: Derreres versions de les Llibreries
- Anotacions: Revisat 07/10/2016.
- Vegeu també: No
compile 'com.android.support:support-v13:24.2.1'
Definim el layout que conté el Viewpager.
- Link al repositori: ViewPager Android
- Anotacions: Revisat 07/10/2016.
- Vegeu també: No
<!-- activity_note_layout.xml -->
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.view.ViewPager
android:id="@+id/activity_note_pager_view_pager"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
Hem de definir una nova activitat que sigui subclasse de FragmentActivity, ja que crearem i tractarem amb Fragments a través del ViewPager. Els fragments són els de la biblioteca de compatibilitat no pas els de la darrera versió del SDK. (Nota: no us oblideu d'afegir l'activitat al manifest Android)
- Link al repositori: Fragment Android
- Anotacions: Modificat el 18/10/2016.
- Vegeu també: ViewPager i List
[...]
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentStatePagerAdapter;
import android.support.v4.view.ViewPager;
[...]
public class NotePagerActivity extends FragmentActivity {
private ViewPager mViewPager;
private List<Note> mNotes;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_note_pager);
mViewPager = (ViewPager) findViewById(R.id.activity_note_pager_view_pager);
mNotes = NoteSingleton.get(this).getNotes();
FragmentManager fragmentManager = getSupportFragmentManager();
mViewPager.setAdapter(new FragmentStatePagerAdapter(fragmentManager) {
@Override
public Fragment getItem(int position) {
Note note = mNotes.get(position);
return NoteFragment.newInstance(note.getId());
}
@Override
public int getCount() {
return mNotes.size();
}
});
}
}
Analitzem el codi pas a pas. En primer lloc carregem el layout que conté el ViewPager i a continuació assignem el propi ViewPager a la variable mViewPager. A mNotes recuperem del singleton la llista amb tots els elements notes (veure apartat Singleton de dades per ampliar informació). A partir d'ara és on es complica, al ViewPager li establim un adaptador del tipus FragmentStatePagerAdapter que com a paràmetre necessita el FragmentManager ja que tractarà el fragments que mostrarà el ViewPager. L'adaptador FragmentStatePagerAdapter ha d'implementar dos mètodes; en primer lloc getItem(position) que ha de retornar un Fragment, concretament el fragment que es voldrà mostrar, i que implementa la vista detallada de l'element de la llista; en segon lloc getCount() que ha de retornar la quantitat d'elements que té la llista per tal que el ViewPager en sigui conscient.
Descarrega l'aplicació d'exemple compilada(apk)
Descarrega el codi font complet de l'aplicació[sdk 22]
FragmentPagerAdapter vs FragmentStatePagerAdapter
modificaFragmentPagerAdapter és la millor opció a l'hora de navegar entre un nombre petit i fix de pàgines. FragmentStatePagerAdapter és la millor opció per la paginació entre una col·lecció d'objectes pel qual el nombre de pàgines es indeterminat; aquest adaptador destrueix els fragments a mida que l'usuari navega a través d'altres pàgines, reduint l'ús de memòria.
Singleton de dades
modificaEn el darrer codi mNotes és un array de Notes però no queda clar d'on recupera les dades. Dons bé, ho fa des d'un singleton de dades anomenat NoteSingleton, que és una classe que només permet una instancia d'ella. Accedim a través del mètode estàtic public get i serà aquest qui cridarà al constructor si s'ha de crear una instància de la classe; en cas contrari sencillament retorna la instància. Un cop tenim recuperada la instància del singleton recuperem totes les notes que hi ha mitjançant el mètode getNotes().
- Link al repositori: Pàgina principal d'Android
- Anotacions: Darrera modificació 18/10/2016.
- Vegeu també: No
<source lang="java">
public class NoteSingleton {
private static NoteSingleton sNoteSingleton;
private ArrayList<Note> mNotes;
public static NoteSingleton get(Context context) {
if (sNoteSingleton == null) {
sNoteSingleton = new NoteSingleton(context);
}
return sNoteSingleton;
}
private NoteSingleton(Context context) {
mNotes = new ArrayList<>();
for (int i = 0; i < 100; i++) {
Note note = new Note();
note.setTitle("Note #" + i);
note.setSolved(i % 2 == 0);
mNotes.add(note);
}
}
public List<Note> getNotes() {
return mNotes;
}
public Note getNote(UUID id) {
for (Note note : mNotes) {
if (note.getId().equals(id)) {
return note;
}
}
return null;
}
}
Tabbed ActionBar
modificaQuè és
modificaL'actionBar d'Android es pot estendre per a mostrar una barra addicional per a facilitar la navegació entre pantalles i per a saber en quina ens trobem. S'empra per a complementar la navegació mitjançant el ViewPager en algunes aplicacions, especialment en aquelles que tenen un nombre fix de pestanyes i que ens interessa que l'usuari conegui. El nombre de pestanyes sol ser fix i petit; per tant hem de veure les pestanyes com un menú entre opcions de l'aplicació i no pas en una manera de moure'ns per una llista d'elements (com en el cas del ViewPager)..
Implementació
modificaEn el moment de crear l'activitat es l'hora d'indicar que volem visualitzar un espai a l'actionBar per les diferents pestanyes que tindrà l'aplicació.
- Link al repositori: Action Bar android
- Anotacions: Revisat el 18/10/2016.
- Vegeu també: Appbar android i Tabbed Action Bar
<source lang="java">
@Override
public void onCreate(Bundle savedInstanceState) {
// Recuperem l'actionBar que porta per defecte tota aplicació Android.
final ActionBar actionBar = getActionBar();
[...]
// Especifiquem que les pestanyes s'han de mostrar a l'Action bar.
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
// Creem el listener de les pestanyes que es crida quan l'usuari canvia entre pestanyes.
ActionBar.TabListener tabListener = new ActionBar.TabListener() {
public void onTabSelected(ActionBar.Tab tab, FragmentTransaction ft) {
// actua al mostrar la pestanya seleccionada.
}
public void onTabUnselected(ActionBar.Tab tab, FragmentTransaction ft) {
// actua quan s'amaga la pestanya al triar-ne una altra.
}
public void onTabReselected(ActionBar.Tab tab, FragmentTransaction ft) {
// actua quan una pestanya es torna a triar. Normalment sense ús.
}
};
// Definim tres pestanyes, amb el seu text i especificant el seu listener de pestanyes.
for (int i = 0; i < 3; i++) {
actionBar.addTab(
actionBar.newTab()
.setText("Tab " + (i + 1))
.setTabListener(tabListener));
}
}
Arribats a aquest punt, tenim un conjunt de pestanyes amb nom que estenen l'actionBar i podem clicar sobre d'elles però el contingut encara no canvia. A continuació definirem què volem que faci l'aplicació quan triem una de les pestanyes que hem creat.
- Link al repositori: Tabbed Action Bar
- Anotacions: Revisat el 18/10/2016.
- Vegeu també: No
<source lang="java>
[..]
public void onTabSelected(ActionBar.Tab tab, FragmentTransaction ft) {
// Quan la pestanya es seleccionada, canvia a la pàgina
// corresponent del ViewPager.
mViewPager.setCurrentItem(tab.getPosition());
}
[...]
Ara ja podem moure'ns per l'aplicació triant la pestanya desitjada, ja que el ViewPager durà a terme la càrrega del Fragment corresponent. Només en resta seleccionar la pestanya adequada cada cop que l'usuari llisca (swipe) entre pàgines del ViewPager.
- Link al repositori: Tabbed Action Bar
- Anotacions: Revisat el 18/10/2016.
- Vegeu també: No
<source lang="java">
[...]
mViewPager = (ViewPager) findViewById(R.id.pager);
mViewPager.setOnPageChangeListener(
new ViewPager.SimpleOnPageChangeListener() {
@Override
public void onPageSelected(int position) {
// Quan llisquem entre pàgines, triem
// la pestanya corresponent.
getActionBar().setSelectedNavigationItem(position);
}
});
[...]
Finalment ja tenim el ViewPager i les pestanyes de la ActionBar lligades entre elles de manera que una actualitzarà l'altra quan l'usuari es mogui per qualsevol dels dos elements.
Diferències entre ViewPager i TabbedActionBar
modificaUn ViewPager ens permet fer transicions ràpides entre elements de llistes lliscant el dit sense la necessitat de tornar a una vista de llista. Tant se val quants elements hi hagi que funciona prou bé. Un clar exemple és l'aplicació de Gmail d'Android, on quan estem consultant un correu podem lliscar cap als costats per a passar al anterior/següent correu.
Tabbed ActionBar mostra una quantitat de pestanyes fixes i conegudes, per moure'ns ràpidament pel contingut com si fossin menús. Es sol combinar amb el Viewpager per dotar de transicions entre els continguts de les diferents pestanyes. Un clar exemple d'aquest ús és l'aplicació YouTube d'Android on per sota de la Toolbar disposem d'una barra amb exactament quatre pestanyes, cadascuna amb una icona i podem passar d'una a l'altre o bé clicant a les icones o bé lliscant cap a un dels costat (ViewPager).