Hvordan bygge en hurtigmenyen i Android App Development

Opprette passende menyer for programmet er avgjørende for å skape en god brukeropplevelse. I den siste opplæringen, så vi på å skape valgmenyen med XML og også på å legge elementer programmatisk. I denne opplæringen, vil vi se på kontekstuelle menyer - menyer som er knyttet til en bestemt del av visningen.

Som i Android 3.0, er det to typer kontekstmenyen: gammel stil flytende menyer, som flyter på skjermen, forankret til elementet klikket på; og kontekstuell handlingsmodus (Android 3.0 og oppover), der en kontekstuell handlingsfeltet (CAB) vises øverst på skjermen. CAB er nå den foretrukne måten å gi en kontekstuell meny, men hvis koden din er kompatibel med Android 2.3 eller tidligere, bør du også gi en flytende versjon for å falle tilbake til. Vi dekker begge alternativene, og også se på hvordan å inkludere både i koden.

Vi vil bruke den samme grunnleggende Gridview kode som i forrige tutorial, og vår kontekstmenyen oppføring vil bruke Intent koden fra den Gridview tutorial, som fyrer av en URL forbundet med bildet klikket på.

Flytende Menyer

Vi begynner med den flytende kontekstmenyen, som du skal bruke for enheter som kjører en eldre versjon enn API 11. Først, la oss lage vår XML-menyen, res /meny /grid_element_menu.xml:?

 < xml version = "1.0" encoding = "UTF-8" > < meny xmlns: android = "http://schemas.android.com/apk/res/android" > < element android: id = "+ id /showUrl" android: title = "@ streng /showUrl_title" /> < /meny > 

Neste håndterer vi det i GridViewTestActivity kode. Vi må legge til en samtale for å registrere nett elementer for hurtigmenyen, og implementere onCreateContextMenu ():

 beskyttet void onCreate (Bundle savedInstanceState) {//som før gridview.setAdapter (gridadapter); registerForContextMenu (Gridview); //Hvile som før} public void onCreateContextMenu (contextmenu meny, Utsikt v, ContextMenuInfo menuInfo) {super.onCreateContextMenu (meny, v, menuInfo); MenuInflater inflater = getMenuInflater (); inflater.inflate (R.menu.grid_element_menu, menyen);} 

registerForContextMenu () assosierer tilgjengelig View (Gridview) med en hurtigmeny. Hvis View er Gridview eller listevisningen, gjør dette registrerer alle sine elementer for den samme hurtigmenyen. For andre visninger, ville du trenger å registrere hver visning for sin egen individuelle kontekstmenyen. onCreateContextMenu () fungerer akkurat på samme måte som den forrige tutorial er onCreateOptionsMenu (), blåse menyen fra XML.

Til slutt, for å gjøre det rette når brukeren klikker på et menyelement, må vi iverksette onContextItemSelected ():

 public boolean onContextItemSelected (MENUITEM element) {AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo (); bryteren (item.getItemId ()) {case R.id.showUrl: Intent i = new Intent (Intent.ACTION_VIEW); i.setData (Uri.parse (gridadapter.getItem (info.position) getImageUrlString ()).); startActivity (i); return true; Standard: returnere super.onContextItemSelected (element); }} 

Her har vi kun ett menyvalg så langt, men vi tillater for å legge mer ved hjelp av en bryter uttalelse. Dette gir også mulighet for å levere menyelementer opp til en superklasse.

kompilere og kjøre, og du vil se din flytende menyen når du lengter klikker på et element.



Contextual Handlingsmeny

Flytte på fra den flytende kontekstmenyen til den nå foretrukket kontekstuell handlingsfeltet (CAB). Det er to måter å lage en CAB. Hvis du ønsker å feste CAB til en bestemt enkelt visning, kan du bruke ActionMode.Callback. (Dette er diskutert i detalj i Android menyer docs.) Men dette fungerer ikke så godt med en Listview eller Gridview. For disse, er du bedre å implementere en MultiChoiceModeListener. Dette gjør at brukeren kan velge flere elementer og deretter bruke et enkelt alternativ til dem. Her imidlertid vi bare bruke vår prøve valg til en enkelt element, for å demonstrere grensesnittet. Når du oppretter din app, bør du vurdere nøye hvilke menyer å bruke under hvilke omstendigheter for å skape den beste brukeropplevelsen

MultiChoiceModeListener ser slik ut (i GridViewTestActivity).

 privat MultiChoiceModeListener modeListener = new MultiChoiceModeListener ( ) {int itemSelectedPosition; public boolean onCreateActionMode (ActionMode modus, Meny menyen) {MenuInflater inflater = mode.getMenuInflater (); inflater.inflate (R.menu.grid_element_menu, menyen); return true; } Public void onItemCheckedStateChanged (ActionMode modus, int posisjon, lang id, boolsk sjekket) {itemSelectedPosition = posisjon; } Public boolean onPrepareActionMode (ActionMode modus, Meny menyen) {//Brukes for oppdateringer til drosje etter ugyldig () forespørsel return false; } Public boolean onActionItemClicked (ActionMode modus, MENUITEM element) {switch (item.getItemId ()) {case R.id.showUrl: Intent i = new Intent (Intent.ACTION_VIEW); i.setData (Uri.parse (gridadapter.getItem (itemSelectedPosition) getImageUrlString ()).); startActivity (i); mode.finish (); return true; standard: return false; }} Public void onDestroyActionMode (ActionMode modus) {//gjør ingenting}}; 

Hvis du sammenligner denne koden til den flytende kontekstmenyen eller til valgmenyen, vil du se mange likheter. Vi blåse opp menyen når det er opprettet, og onActionItemClicked () nok en gang har bryteren koden vi har sett før. Denne gangen om vi trenger å få posisjonen til det valgte elementet fra en annen metode, onItemCheckedStateChanged (). Vær oppmerksom på at vi bare har en eneste int å lagre elementet posisjon i, hver gang et element er valgt eller ikke valgt, vil dette int bli overskrevet. Dette betyr at vi kun har sende en enkelt URL (av elementet sist klikket) med Intent. Hvis vi ønsket å være i stand til å handle på flere elementer (for eksempel for å slette dem, eller å dele dem alle), ville vi trenger å holde styr på alle de valgte elementene.

Etter å ha opprettet MultiChoiceModeListener, tar det bare to linjer for å sette den opp i GridViewTestActivity:

 beskyttet void onCreate (Bundle savedInstanceState) {//som før gridview.setChoiceMode (GridView.CHOICE_MODE_MULTIPLE_MODAL); gridview.setMultiChoiceModeListener (modeListener);} 

kompilere og kjøre, og en lang-klikk vil produsere CAB

Du kan også bruke ActionMode å gjøre endringer i den kontekstuelle handlingsfeltet.. For eksempel kan du sette en egendefinert tittel eller undertittel:

 public boolean onCreateActionMode (ActionMode modus, Meny-menyen) {//som før mode.setTitle ("Handling Bar!"); mode.setSubtitle ("Subtitle"); return true;} 

Dette skjermbildet viser hvor de vil dukke opp. Se ActionMode docs for andre alternativer.


En annen forbedring i koden ville være å endre bakgrunnsfargen på noen utvalgte elementer, eller å sette opp en avkrysnings, for å vise hvor varen (e) har blitt valgt. Anmeldelser
Håndtering Reserve

Hvis du kode både den flytende menyen og CAB, og kjøre den på en Android-enhet som kjører API 11 eller høyere, vil den flytende menyen bli ignorert til fordel for CAB, som nå er det foretrukne alternativet for kontekstuelle menyer. For å gjøre koden kjøre ved hjelp av flytende menyen på tidligere API versjoner også, kan du kode en API sjekk:

 beskyttet void onCreate (Bundle savedInstanceState) {//som tidligere //neste linje erstatter setChoiceMode () og setMultiChoice .. () linjer setUpContextualActionBar (); } private void setUpContextualActionBar () {if (Build.VERSION.SDK_INT > = Build.VERSION_CODES.HONEYCOMB) {gridview.setChoiceMode (GridView.CHOICE_MODE_MULTIPLE_MODAL); gridview.setMultiChoiceModeListener (ny MultiChoiceModeListener () {//kode for å sette opp MultiChoiceModeListener som før}); }} 

Du må også legge til et notat ved starten av klassen, for å undertrykke API kompatibilitet advarsler og la koden for å kompilere:

SuppressLint ("NewApi") public class GridViewTestActivity strekker Aktivitet 

Du bør bare gjøre dette hvis du er veldig sikker på at du har pakket alle dine nye API-kode i passende hvis klausuler eller på annen måte beskyttet den. For mer på å støtte flere plattformer og APIer, se Android-docs


For mer i denne serien kan du se:.

Android App Development: Hvordan lage en meny med alternativer