Preambolo
Come al solito, ho dovuto affrontare un problema strano, mentre lo sviluppo di un'app per Android, ho cercato di trovare una soluzione e sono arrivato a questa domanda. Come in molti casi prima, non c'è una risposta. Così sono stato costretto a risolvere il problema da zero e ora postando la risposta con la mia soluzione alternativa.
ingresso
Ho un app Android con barra di azione e di alcune voci di menu, che devono essere esteso con sottomenu a tendina. Il primo tentativo è stato implementarlo come suggerito dalla documentazione di Android. Così ho aggiunto nuova voce di menu menu_sort
in esistente menù barra delle azioni e sub menu
contenitore in esso:
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:id="@+id/id1" android:icon="@drawable/ic_1"
android:title="@string/id1" android:showAsAction="withText|always"/>
...
<item
android:id="@+id/menu_sort"
android:icon="@drawable/ic_menu_sort_selector"
android:title="▾"
android:titleCondensed="▾"
android:showAsAction="withText|always">
<menu>
<item
android:id="@+id/menu_sort_by_name"
android:showAsAction="never"
android:checkable="true"
android:checked="true"
android:title="@string/sort_by_name"/>
<item
android:id="@+id/menu_sort_by_priority"
android:showAsAction="never"
android:checkable="true"
android:checked="false"
android:title="@string/sort_by_priority"/>
<item
android:id="@+id/menu_sort_by_memory"
android:showAsAction="never"
android:checkable="true"
android:checked="false"
android:title="@string/sort_by_memory"/>
</menu>
</item>
</menu>
Risultato
L'effetto è stato esattamente come descritto nella domanda: il sottomenu viene visualizzato sulla parte superiore della barra delle azioni. Ecco lo screenshot preso su Android 5.1.1:
ho giocato con molte opzioni e frammenti di codice - non serviva a niente. Finalmente sono giunto alla seguente
Soluzione
In primo luogo, spostare tutto il sottomenu in un layout menu separato, per esempio, menu/sorting.xml
, e rimuoverla dalla menu_sort
voce del menù principale (mostrato sopra).
In secondo luogo, modificare o creare onPrepareOptionsMenu
gestore di eventi con il seguente codice:
@Override
public boolean onPrepareOptionsMenu(Menu menu)
{
// as solution utilizes PopupMenu,
// take care about older Android versions if necessry
// if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB)
// here goes most crazy part: we use menu id
// to retrieve corresponding view, automatically created by OS;
// imho, this is a hack, and menu item should have getView() method or similar;
View menuItemView = findViewById(R.id.menu_sort);
// by the way, menuItemView could probably be null under some circumstances
// create a popup anchored to the view (menu item)
final PopupMenu popupMenu = new PopupMenu(this, menuItemView);
// API 14
// popupMenu.inflate(R.menu.sorting);
// API 11 (HONEYCOMB)
popupMenu.getMenuInflater().inflate(R.menu.sorting, popupMenu.getMenu());
// process popup clicks as appropriate
popupMenu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener()
{
@Override
public boolean onMenuItemClick(MenuItem item)
{
switch(item.getItemId())
{
// ... place some code
}
return true;
}
});
// bind the popup to the item menu
menu.findItem(R.id.menu_sort).setOnMenuItemClickListener(new OnMenuItemClickListener()
{
@Override
public boolean onMenuItemClick(MenuItem item)
{
popupMenu.show();
return true;
}
});
return super.onPrepareOptionsMenu(menu);
}
Ecco il risultato:
Ora la discesa viene visualizzato come previsto dal principio.
capito? – JackyBoi
Lo stesso problema è qui (Android 5.1). Dopo diversi anni di inciampare su tali "caratteristiche" qua e là durante lo sviluppo per Android, devo dire che Android è una piattaforma molto frustrante, ahimè. – Stan