Kurs Android

Menu

Ważnym i stosunkowo łatwym do obsługi elementem jest menu. Jest ono wywoływane po naciśnięciu odpowiadającemu mu przycisku. Zawiera w większości przypadków opcje których nie chcemy umieszczać bezpośrednio na ekranie, ponieważ są rzadko używane.

Jak w większości kontrolek Androidowych menu możemy tworzyć na dwa sposoby. Jednym jest plik xml, drugim napisanie go w kodzie. Mimo, ze jestem przekonany o tym ze dużo lepiej jest korzystać z xml pokażę jak to robić na dwa sposoby.

 

1. Tworzenie menu korzystając z XML (sugerowane)

2. Tworzenie menu z poziomu kodu

3. Obsługa zdarzenia naciśnięcia przycisku menu

 

Można wyróżnić trzy typy elementów menu:

  • tekstowe
  • obrazkowe
  • tekst + obrazek

Posłużę się przykładem. Oto nasze docelowe menu:

Chcemy utworzyć trzy elementowe menu. Pierwszy przycisk oznaczony jest tylko napisem, drugi tylko obrazkiem a trzeci posiada obydwa atrybuty.

Przed przystąpieniem do tworzenia menu należy znaleźć sobie odpowiednią ikonkę i umieścić w katalogu /res/drawable/

Tworzenie menu korzystając z XML

Kod który dodajemy do Activity w którym chcemy aby pojawiało się menu:

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
   }

Plik /res/menu/menu.xml, można go znaleźć tutaj:

Zawartość:

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

    <item
        android:id="@+id/item1"
        android:orderInCategory="1"
        android:title="Jeden">
    </item>
    <item
        android:id="@+id/item2"
        android:icon="@drawable/android_icon"
        android:orderInCategory="2">
    </item>
    <item
        android:id="@+id/item3"
        android:icon="@drawable/android_icon"
        android:orderInCategory="3"
        android:title="Trzy">
    </item>

</menu>

I tyle. Powinno działać.

 

Tworzenie menu z poziomu kodu

 

	public static final int PIERWSZY_ELEMENT = 1;
	public static final int DRUGI_ELEMENT = 2;
	public static final int TRZECI_ELEMENT = 3;

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {

		menu.add(0, PIERWSZY_ELEMENT, 0, "Jeden");
		menu.add(1, DRUGI_ELEMENT, 0, "").setIcon(R.drawable.android_icon);
		menu.add(2, TRZECI_ELEMENT, 0, "Trzy").setIcon(R.drawable.android_icon);

        return true;
    }

Obsługa naciśnięcia przycisku menu

Obsługę naciśnięcia opcji menu realizujemy wstawiając poniższy kod do Activity w którym ono występuje, odwołując się do numeru id przycisku.

 

Dla xml'a wygląda to następująco: (item1, item2, item3 to oczywiście nazwy elementów menu)

@Override
	public boolean onOptionsItemSelected(MenuItem item) {

		String ktoryElement = "";

		switch (item.getItemId()) {

		case R.id.item1:
			ktoryElement = "pierwszy";
			break;
		case R.id.item2:
			ktoryElement = "drugi";
			break;
		case R.id.item3:
			ktoryElement = "trzeci";
			break;
		default:
			ktoryElement = "żaden";

		}

		Toast.makeText(getApplicationContext(), "Element: " + ktoryElement,
				Toast.LENGTH_LONG).show();

		return true;
	}

 

Natomiast dla menu tworzonego w kodzie uzyskujemy niemal identyczny kod. Odwołujemy się tutaj do wcześniej ustalonych stałych id elementów menu.

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {

		String ktoryElement = "";

		switch (item.getItemId()) {

		case PIERWSZY_ELEMENT:
			ktoryElement = "pierwszy";
			break;
		case DRUGI_ELEMENT:
			ktoryElement = "drugi";
			break;
		case TRZECI_ELEMENT:
			ktoryElement = "trzeci";
			break;
		default:
			ktoryElement = "żaden";

		}

		Toast.makeText(getApplicationContext(), "Element: " + ktoryElement,	Toast.LENGTH_LONG).show();

		return true;
	}

 

 

Menu jest niezwykle prostym do obsługi i tworzenia elementem. Jeśli jednak macie pytania - to jak zwykle walić śmiało! :)

Komentarze

Michał

Niedawno czytałem post tech writera developer.android.com, który właściwie deprecjonuje menu, o którym tu napisałeś na rzecz action bara. Faktycznie coraz mniej urządzeń posiada przycisk fizyczny + jest to moim zdaniem bardzo mało intuicyjna praktyka, która "chowa" część funkcjonalności aplikacji. Można w ten sposób całkiem skutecznie sprawić, iż użytkownicy nigdy nie skorzystają z tych wszystkich rzeczy, które tak pracowicie zakodowaliśmy.

Link do postu: http://android-developers.blogspot.com/2012/01/say-goodbye-to-menu-button.html

Marcin Kunert

Racja, w nowszych wersjach nie stosuje się już menu. Większość urządzeń korzysta jeszcze z wcześniejszych wersji. (źródło: http://developer.android.com/about/dashboards/index.html)
Na szczęście słyszałem coś o bibliotece umożliwiającej korzystanie z ActionBara niego pod 2.3.3 i z pewnością przyjrzę się temu bliżej.

Dzięki za link.
Pozdro!

Tymon Radzik

Drobny błąd,ale rzeczywiście trzeba na to zwrócić uwagę.

Polok

Jeśli mowa o wspieraniu Actionbarach w wersjach Androida >= 2.3.3 to polecam SherlockActionBar - http://actionbarsherlock.com/

mlecz

W tutorialu (tekstem) zamiast:
/res/menu/menu.xml
powinno być:
/res/menu/main.xml jak na screenie
Jak ktoś ma problem z kompilacją, to jak sami ikonki nie wrzucicie- nie zadziała.

Michał

Witam!
czy mógłbym się spytać jak zrobić menu w stylu "Googlowym"?
Czyli takie jak w Mapach, Google+ (i pewnie innych).

Pozdrawiam,
Michał

Hookz

Przy okazji pytanie- czy zrobicie trochę tutoriala o używaniu Action Bar Sherlock?
Bo przydałoby się ( w internecie bardzo mało informacji...:( )

Loony

"Przed przystąpieniem do tworzenia menu należy znaleźć sobie odpowiednią ikonkę i umieścić w katalogu /res/drawable/"

Nie ma folderu /res/drawable/, są tylko tam drawable-hdpi, drawable-ldpi, drawable-mdpi itd. Jakie rozszerzenie dać tej ikony?

Marcin Kunert

Hej!
Możesz utworzyć sobie ręcznie folder drawable, albo wrzucić do każdego z nich (docelowo w hdpi powinna być ikona w największej jakości, a w ldpi najmniejszej)
Rozszerzeniem pliku może być: jpg, png albo gif.

Loony

No hej ;)
Właśnie przeskalowałem sobie te ikonki w odpowiednich rozmiarach (72, 48, 96, 144) i powrzucałem odpowiednio tam pod nazwą android_icon z rozszerzeniem .jpg ale coś nie odpala. Teraz zrobiłem folder "drawable", odpaliłem tym razem na emulatorze ale wciąż to samo - nie widać ikonki. Oto SS emulatora i IDE w tle: http://fooh.pl/pokaz/1167815598.png

Marcin Kunert

Robisz wszystko dobrze. Problem w tym, że w nowszych wersjach androida odchodzi się od menu na rzecz action bara.
Jeśli zmienisz środowisko na API 10, to ikonka powinna być widoczna.

GJeszka

Dzięki, bo zmarnowałem 30 minut :P
Gdzie ta kompatybilność wsteczna....

GJeszka

Faktycznie, nie miałem api 10.

Loony

No faktycznie, dopiero po doinstalowaniu SDK Level 10 i postawieniu emulatora z wersją 2.3.3 działa. Dzięki za tak szybką odpowiedź ;).

Loony

Kurde, to miała być odpowiedź na http://javastart.pl/programowanie-android/menu/#comment-11840, a napisałem nowy post ;).

Asylum_of_glass

Jest jakiś sposób, na to, żeby takie menu było dostępne z każdego miejsca w aplikacji (w każdej aktywności)? Czy po prostu trzeba w każdej aktywności wpisywać kod obsługi menu?

Marcin Kunert

Możesz stworzyć swoje abstrakcyjne MyActivity które dodaje to menu, a w aplikacji zamiast dziedziczyć po Activity, dziedziczyć po MyActivity.

Asylum_of_glass

Dzięki za odpowiedź, już mam menu dostępne w każdej aktywności. :)
Proste, intuicyjne i skuteczne rozwiązanie, ale sam bym na to nie wpadł, dziękuję za ten pomysł.

michal

Witam!
Zachęcasz, to stawiam pytanie:
Co to znaczy "Tworzenie menu z poziomu kodu" ?
A gdybym chciał napisać aplikację całą "z poziomu kodu" ?
-Lepiej człowiek panuje nad całąścią, tak mi się zdaje.
Tylko jak kompilować?
Pozdr.
Michał

Kostek

Robię wszystko jak w instrukcji, nie ma żadnych błędów, ale menu się nie wyświetla. Od razu przechodzi do aplikacji, czyli w moim wypadku wyrzuca Hello World.

Marcin Kunert

Naciśnij przycisk "menu" w telefonie (a jeśli masz nowszy telefon to poczytaj o ActionBar)

Kostek

Aaaaa.. No tak.. To zmienia postać rzeczy, teraz działa, wielkie dzięki. Nie spodziewałem się tak szybkiej odpowiedzi ;]

Kostek

EDIT: Jednak są błędy w LogCat. error opening trace file: no such a file or directory.

A narazie nie dodawałem żadnych ikon, po prostu tytuł danego elementu menu

Krzych

Jeśli naciskam przycisk menu np. title="Jeden" to jak zrobić żeby przycisk zmienił nazwę na title="Dw" ?

Smykel

Ja jestem całkowicie świeży w temacie programowania. Staram się robić krok po kroku jak w tutorialu jest to opisane. Niestety kiedy kompiluje aplikację i chcę ją otworzyć na swoim Note 3 dostaję komunikat że aplikacja została zamknięta. Nie bardzo wiem jak sobie tym poradzić gdyż w samym kodzie nie mam żadnych błędów.

Lolo

Napisz wątek na forum(na górze strony masz link do forum) i daj tam loga z logcata. To może coś uradzimy.