Príkladom je navigačný panel v GMaili:
Tento panel tak predstavuje akýsi rázcestník pre činnosti používateľa. Často sa používa vo chvíľach, keď už karty na lište akcií nevyhovujú, pretože je ich primnoho.
Navigačný panel má dva stavy:
Stavy panelu možno prepínať nielen ťahaním spoza okraja displeja, ale aj kliknutím na ikonu appky v lište akcií.
Na vytvorenie výsuvného panelu potrebujeme:
DrawerLayout
ActionBarDrawerToggle
, ktorým budeme prepínať vysunutý a zasunutý stav pomocou ikony appky na lište akciíVýsuvný panel získame prakticky zadarmo: potrebujeme však v aktivite deklarovať layout typu android.support.v4.widget.DrawerLayout
. Do layoutového súboru aktivity activity_main.xml
teda dajme tento kód (nahraďme ním existujúci RelativeLayout):
<android.support.v4.widget.DrawerLayout
xmlns:android="https://schemas.android.com/apk/res/android"
xmlns:tools="https://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity"
android:id="@+id/drawerLayout"
>
<LinearLayout android:id="@+id/contentLayout"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
<ListView android:id="@+id/navigationListView"
android:layout_height="match_parent"
android:layout_width="240dp"
android:layout_gravity="start"
android:background="@android:color/holo_orange_light"
android:entries="@array/shopNavigationItems"
>
</ListView>
</android.support.v4.widget.DrawerLayout>
V layoute deklarujeme dva významné elementy:
layout_gravity
s hodnotou start
umiestni panel vľavo. Voliteľne ešte môžeme nastaviť pozadie (background
) a položky zoznamu reprezentované odkazom na resource typu pole.Položky zoznamu sú reprezentované cez resource súbor typu pole (array
). Vložme do súboru strings.xml
element <string-array>
, v ktorom deklarujeme položky zoznamu vo výsuvnom navigačnom paneli.
<resources>
...
<string-array name="shopNavigationItems">
<item>Hry</item>
<item>Knihy</item>
<item>Filmy</item>
</string-array>
</resources>
V layoute aktivity sa odkážeme na resource s poľom cez @array/shopNavigationItems
.
Kód aktivity, ktorá poskytne prvú verziu vysúvacieho panela, môže byť minimalistický:
import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.widget.ListView;
public class MainActivity extends ActionBarActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
}
Nič špeciálne, vlastne... nič tu nie je. Ale po spustení uvidíme layout v akcii! Síce to bude skôr počítačová adventúra, pretože jediný spôsob, ako vysunúť navigačný panel, je ťahať prstom (myšou) spoza ľavého okraja displeja, ale už vidíme základné správanie panela.
V ďalšom kroku nachystáme lištu akcií: zobrazíme na nej tlačidlo s ikonou, ktorá bude klikateľná a zároveň umožní vysúvať a zasúvať panel. Do metódy onCreate()
teda dodáme:
getSupportActionBar().setHomeButtonEnabled(true);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
Keďže vysúvací panel využíva knižnicu kompatibility a interaguje so spätne kompatibilnou lištou akcií, musíme inštanciu lišty získavať volaním getSupportActionBar()
. Výsledok metódy getActionBar()
v tomto prípade vracia null
.
O niečo neskôr sa z tejto ikony stane spomínaný hamburger, ktorým budeme roztvárať panel.
Na ozajstné oživenie tlačidla potrebujeme získať referenciu na DrawerLayout
a vytvoriť ActionBarDrawerToggle
, teda widget s ikonou hamburgeru.
Toggle má konštruktor, ktorý je prinajmenšom podivný:
DrawerLayout
u, ktorú získame pomocou findViewById()
,R.string.openDrawer
a R.string.closeDrawer
, ktoré vytvoríme dodatočne.Tlačidlo teda vytvorme a priraďme do inštančnej premennej typu ActionBarDrawerToggle
.
drawerToggle = new ActionBarDrawerToggle(this,
drawerLayout,
R.string.openDrawer,
R.string.closeDrawer
);
Toggle má dve implementácie: jednu z knižnice v4 a novšiu z knižnice v7. V ukážke používame novšiu verziu z balíčka android.support.v7.app.ActionBarDrawerToggle
.
V tejto chvíli je samozrejme dvojica zázračných parametrov zvýraznená chybou. Našťastie, Studio umožní klávesovou skratkou Alt-Enter využiť pomoc Create String resource value 'openDrawer'.
Stačí v dialógu vyplniť hodnotu a výsledok sa objaví v súbore strings.xml
.
Postup zopakujeme ešte raz a nahliadnime do súboru, kde uvidíme dve deklarácie:
<resources>
...
<string name="openDrawer">Otvoriť</string>
<string name="closeDrawer">Zatvoriť</string>
...
</resources>
Ak máme panel reprezentovaný DrawerLayout
om a tlačidlo toggle, prepojíme ich jednoducho: panel umožnuje registráciu poslucháča na vysúvanie a zasúvanie a práve tlačidlo môže byť takýmto poslucháčom.
drawerLayout.setDrawerListener(drawerToggle);
Celý kód metódy onCreate()
vyzerá nasledovne:
private ActionBarDrawerToggle drawerToggle;
private DrawerLayout drawerLayout;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
getSupportActionBar().setHomeButtonEnabled(true);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
drawerLayout = (DrawerLayout) findViewById(R.id.drawerLayout);
drawerToggle = new ActionBarDrawerToggle(this,
drawerLayout,
R.string.openDrawer,
R.string.closeDrawer
);
drawerLayout.setDrawerListener(drawerToggle);
}
Aby to všetko fungovalo správne, musíme synchronizovať stav aktivity s tlačidlom po vytvorení aktvity:
@Override
protected void onPostCreate(Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState);
drawerToggle.syncState();
}
Podobne musíme synchronizovať stav pri zmene konfigurácie systému:
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
drawerToggle.onConfigurationChanged(newConfig);
}
Tlačidlo hamburgera sa pre účely obsluhy tvári ako akékoľvek iné tlačidlo. Ak ho chceme obslúžiť, v metóde onOptionsItemSelected()
najprv delegujeme volanie tejto metódy na toggle. Ak toggle nedokáže obslúžiť aktuálne vybrané tlačidlo na lište akcií (napríklad klikáme na iné tlačidlo než toggle), využijeme štandardné správanie:
@Override
public boolean onOptionsItemSelected(MenuItem item) {
if(drawerToggle.onOptionsItemSelected(item)) {
return true;
}
return super.onOptionsItemSelected(item);
}
Ak chceme obslúžiť kliknutie na položku zoznamu vo výsuvnom paneli, použijeme známe veci. V metóde onCreate()
si vytiahneme z layoutu zoznam ListView
a pridáme mu poslucháča na kliknutie. Poslucháčom môže byť aktivita:
ListView navigationListView = (ListView) findViewById(R.id.navigationListView);
navigationListView.setOnItemClickListener(this);
Samozrejme, tá musí implementovať interfejs OnItemClickListener
a poskytnúť príslušnú metódu:
public class MainActivity ... implements AdapterView.OnItemClickListener {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
...
}
}
V metóde potom môžeme zamienať fragmenty v hlavnom obsahu, alebo spúšťať nové aktivity, čím úplne oživíme výsuvný panel. V ukážke si zistíme reťazec s popiskom v položke, na ktorú sa kliklo a nastavíme ho ako hlavičku aktivity. Následne ešte musíme zavrieť vysúvací panel.
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
String selectedItemTitle = (String) parent.getAdapter().getItem(position);
setTitle(selectedItemTitle);
drawerLayout.closeDrawers();
}
Výsledný kód aplikácie možno nájsť v Githube v repozitári novotnyr/android-drawerlayout-demo-2015
.