2009-01-11 12 views
39

Wie implementieren Sie ein Kontextmenü, das durch einen langen Klick ausgelöst wird, oder tippen Sie auf eine ListActivity, die die integrierten Layouts und einen ListAdapter verwendet?Wie implementieren Sie das Kontextmenü in einer ListActivity auf Android?

+3

Ihre Bearbeitung hat die Frage tatsächlich vollständig geändert. Wäre wahrscheinlich besser gewesen, nur die andere Frage zu stellen. –

Antwort

73

Auf der onCreate Methodenaufruf registerForContextMenu wie folgt aus:

registerForContextMenu(getListView()); 

und dann füllen Sie das Menü auf onCreateContextMenu(ContextMenu menu, View view, ContextMenuInfo menuInfo). Das MenuInfo Argument kann darüber informieren, welche Gegenstand wurde auf diese Weise lange geklickt:

AdapterView.AdapterContextMenuInfo info; 
try { 
    info = (AdapterView.AdapterContextMenuInfo) menuInfo; 
} catch (ClassCastException e) { 
    Log.e(TAG, "bad menuInfo", e); 
    return; 
} 
long id = getListAdapter().getItemId(info.position); 

und Sie Menüpunkte in der üblichen Art und Weise ruft menu.add hinzu:

menu.add(0, MENU_ITEM_ID, 0, R.string.menu_string); 

und wenn der Benutzer wählt eine Option , onContextItemSelected heißt. Auch onMenuItemSelected und diese Tatsache wird nicht explizit in der Dokumentation erklärt, außer zu sagen, dass Sie die andere Methode verwenden, um die Aufrufe aus dem Kontextmenü zu empfangen; Seien Sie sich dessen bewusst, teilen Sie keine IDs.

Auf onContextItemSelected Sie ahold des MenuInfo bekommen kann und somit die ID des Elements ausgewählt von getMenuInfo() Aufruf:

try { 
    info = (AdapterView.AdapterContextMenuInfo) item.getMenuInfo(); 
} catch (ClassCastException e) { 
    Log.e(TAG, "bad menuInfo", e); 
    return false; 
} 
long id = getListAdapter().getItemId(info.position); 
+1

Ahh, danke. Überall im Web gesucht, konnte aber nur die alte Version finden. Dieser funktioniert perfekt mit Cupcake. –

+2

Ich weiß, dass der ClassCastException-Sicherheitscode im Google-Beispiel angezeigt wird, aber ich denke, dass dies wahrscheinlich unnötig ist. Es ist nicht wahrscheinlich, dass die MenuInfo nur manchmal eine AdapterContextMenuInfo ist - es wird wahrscheinlich immer oder nie sein. Die Wächterklausel verhindert, dass die App abstürzt, aber Sie haben trotzdem einen Logikfehler. Ich persönlich würde eher die ganze Stack-Spur sehen, aber das ist nur meine Vorliebe. –

+1

@Daniel Yankowsky: Wenn Sie 'registerForContextMenu' nur einmal benutzen: ja. Bei einem benutzerdefinierten Listenaktivitätslayout können Sie jedoch auch andere Elemente registrieren. Aber dann: Wäre es nicht besser, instanceof zu verwenden und zu überprüfen, was du hast? - Ahh, naja, ich habe noch nie einen guten Democode gesehen. – Martin

5
listView = (ListView) findViewById(R.id.listpockets); 
registerForContextMenu(listView); 



public void onCreateContextMenu(android.view.ContextMenu menu, View v, android.view.ContextMenu.ContextMenuInfo menuInfo) { 
    //AdapterContextMenuInfo info = (AdapterContextMenuInfo)menuInfo; 
    menu.setHeaderTitle(getString(R.string.titleDelete)); 
    menu.add(0, CommonUtil.CONTEXT_MENU__DELETE_ID, 0, getString(R.string.menuDelete)); 
}; 
@Override 
public boolean onContextItemSelected(MenuItem item) { 

    if(item.getItemId() == CommonUtil.CONTEXT_MENU__DELETE_ID) 
    { 
     AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo(); 
     long id = this.listView.getItemIdAtPosition(info.position); 
     Log.d(TAG, "Item ID at POSITION:"+id); 
    } 
    else 
    { 
     return false; 
    } 
    return true; 
} 
Verwandte Themen