Menu Opzioni Android in Frammento
-
25-10-2019 - |
Domanda
Sto cercando di aggiungere una voce al menu di opzioni da un gruppo di frammenti.
Ho creato una nuova classe MenuFragment
ed esteso questo per i frammenti desidero includere la voce di menu nella Ecco il codice:.
public class MenuFragment extends Fragment {
MenuItem fav;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
}
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
fav = menu.add("add");
fav.setIcon(R.drawable.btn_star_big_off);
}
}
Per qualche motivo il onCreateOptionsMenu
non sembra correre.
Soluzione
Chiamare il metodo super:
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
}
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
// TODO Add your menu entries here
super.onCreateOptionsMenu(menu, inflater);
}
dichiarazioni di registro mettere nel codice per vedere se il metodo non viene chiamato o se il menu non viene modificata dal codice.
Assicurarsi inoltre che si sta chiamando setHasOptionsMenu(boolean)
in onCreate(Bundle)
per notificare il frammento che dovrebbe partecipare nella gestione menu delle opzioni.
Altri suggerimenti
Ho avuto lo stesso problema, ma penso che sia meglio di riassumere e presentare l'ultimo passo per farlo funzionare:
-
Aggiungi metodo setHasOptionsMenu (true) nel metodo
onCreate(Bundle savedInstanceState)
di Fragment. -
Override
onCreateOptionsMenu(Menu menu, MenuInflater inflater)
(se si vuole fare qualcosa di diverso nel vostro menu del frammento) e metodionOptionsItemSelected(MenuItem item)
nel frammento. -
All'interno metodo vostra
onOptionsItemSelected(MenuItem item)
di attività, assicurarsi di restituire FALSE quando l'azione voce di menu sarebbe stato attuato nel metodoonOptionsItemSelected(MenuItem item)
di Fragment.
Un esempio:
attività
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getSupportMenuInflater();
inflater.inflate(R.menu.main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.activity_menu_item:
// Do Activity menu item stuff here
return true;
case R.id.fragment_menu_item:
// Not implemented here
return false;
default:
break;
}
return false;
}
Frammento
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
....
}
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
// Do something that differs the Activity's menu here
super.onCreateOptionsMenu(menu, inflater);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.activity_menu_item:
// Not implemented here
return false;
case R.id.fragment_menu_item:
// Do Fragment menu item stuff here
return true;
default:
break;
}
return false;
}
Se si trova il metodo onCreateOptionsMenu(Menu menu, MenuInflater inflater)
non viene invocato, assicurarsi di chiamare il seguente dal metodo di onCreate(Bundle savedInstanceState)
del Fragment:
setHasOptionsMenu(true)
Se avete bisogno di un menu
di aggiornare un webview
all'interno di una specifica Fragment
, è possibile utilizzare:
Frammento :
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
}
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
// TODO Add your menu entries here
inflater.inflate(R.menu.menu, menu);
super.onCreateOptionsMenu(menu, inflater);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.exit:
System.exit(1);
break;
case R.id.refresh:
webView.reload();
break;
}
return true;
}
menu.xml
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="@+id/exit" android:title="Exit" android:icon="@drawable/ic_action_cancel" />
<item android:id="@+id/refresh" android:title="Refresh" android:icon="@drawable/ic_action_refresh" />
</menu>
Nel menu.xml
si dovrebbe aggiungere tutte le voci di menu. Poi si può nascondere gli elementi che non si vuole vedere nel caricamento iniziale.
menu.xml
<item
android:id="@+id/action_newItem"
android:icon="@drawable/action_newItem"
android:showAsAction="never"
android:visible="false"
android:title="@string/action_newItem"/>
Add setHasOptionsMenu(true)
nel metodo onCreate () per richiamare le voci di menu nella classe frammento.
FragmentClass.java
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
}
Non c'è bisogno di sostituzione onCreateOptionsMenu
nella classe Frammento di nuovo. Le voci di menu possono essere cambiati (Aggiungi / Rimuovi) sovrascrivendo onPrepareOptionsMenu
method disponibili in Frammento.
@Override
public void onPrepareOptionsMenu(Menu menu) {
menu.findItem(R.id.action_newItem).setVisible(true);
super.onPrepareOptionsMenu(menu);
}
TL; DR
Usa il android.support.v7.widget.Toolbar
e solo fare:
toolbar.inflateMenu(R.menu.my_menu)
toolbar.setOnMenuItemClickListener {
onOptionsItemSelected(it)
}
Standalone Toolbar
La maggior parte delle soluzioni proposte come setHasOptionsMenu(true)
lavorano solo quando il genitore attività ha la barra degli strumenti nel suo layout e dichiara tramite setSupportActionBar()
. Poi i frammenti possono partecipare la popolazione menu di questo esatto ActionBar :
Fragment.onCreateOptionsMenu ():. Inizializza il contenuto del menu di opzioni standard del padrone di casa Frammento
Se si desidera una barra degli strumenti stand-alone e menù per una specifica Frammento è possibile effettuare le seguenti operazioni:
menu_custom_fragment.xml
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/menu_save"
android:title="SAVE" />
</menu>
custom_fragment.xml
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
...
CustomFragment.kt
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
val view = inflater.inflate(layout.custom_fragment, container, false)
val toolbar = view.findViewById<Toolbar>(R.id.toolbar)
toolbar.inflateMenu(R.menu.menu_custom_fragment)
toolbar.setOnMenuItemClickListener {
onOptionsItemSelected(it)
}
return view
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
return when (item.itemId) {
R.id.menu_save -> {
// TODO: User clicked the save button
true
}
else -> super.onOptionsItemSelected(item)
}
}
Sì, è così facile. Non c'è nemmeno bisogno di onCreate()
esclusione o onCreateOptionsMenu()
.
PS:. Questo è il lavoro solo con i android.support.v4.app.Fragment
e android.support.v7.widget.Toolbar
(anche assicurarsi di utilizzare AppCompatActivity
e un tema AppCompat
nel vostro styles.xml
)
È necessario utilizzare menu.clear () prima di gonfiare i menu.
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
menu.clear();
inflater.inflate(R.menu.menu, menu);
super.onCreateOptionsMenu(menu, inflater);
}
e
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
}
Nel mio caso, ecco i passi.
Step-1
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Here notify the fragment that it should participate in options menu handling.
setHasOptionsMenu(true);
}
Step-2
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
// First clear current all the menu items
menu.clear();
// Add the new menu items
inflater.inflate(R.menu.post_stuff, menu);
super.onCreateOptionsMenu(menu, inflater);
}
Step-3
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.post_stuff:
Log.d(TAG, "Will post the photo to server");
return true;
case R.id.cancel_post:
Log.d(TAG, "Will cancel post the photo");
return true;
default:
break;
}
return super.onOptionsItemSelected(item);
}
Se si desidera aggiungere il menu personalizzato
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
}
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.menu_custom, menu);
}
Ho avuto lo stesso problema, i miei frammenti erano pagine di un ViewPager. Il motivo che stava accadendo è che stavo usando direttore frammento bambino, piuttosto che l'attività di direttore frammento sostegno quando un'istanza FragmentPagerAdapter.
file Menu:
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="@+id/play"
android:titleCondensed="Speak"
android:showAsAction="always"
android:title="Speak"
android:icon="@drawable/ic_play">
</item>
<item
android:id="@+id/pause"
android:titleCondensed="Stop"
android:title="Stop"
android:showAsAction="always"
android:icon="@drawable/ic_pause">
</item>
</menu>
Codice attività:
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.speak_menu_history, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.play:
Toast.makeText(getApplicationContext(), "speaking....", Toast.LENGTH_LONG).show();
return false;
case R.id.pause:
Toast.makeText(getApplicationContext(), "stopping....", Toast.LENGTH_LONG).show();
return false;
default:
break;
}
return false;
}
frammento di codice:
@Override
public void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.play:
text = page.getText().toString();
speakOut(text);
// Do Activity menu item stuff here
return true;
case R.id.pause:
speakOf();
// Not implemented here
return true;
default:
break;
}
return false;
}
Il tuo codice va bene. Solo il super mancava nel metodo:
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
// TODO add your menu :
inflater.inflate(R.menu.my_menu, menu);
//TODO call super
super.onCreateOptionsMenu(menu, inflater);
}
mi è stato sempre pazzesco perché nessuna delle risposte qui ha lavorato per me.
Per visualizzare il menu ho dovuto chiamare: setSupportActionBar(toolbar)
Fatto!
Nota: se la vostra vista toolbar
non si trova lo stesso layout di attività non è possibile utilizzare la chiamata sopra direttamente dalla vostra classe di attività, in questo caso avrete bisogno di ottenere che l'attività dalla classe frammento e quindi chiamare la setSupportActionBar(toolbar)
. Ricordando:. La classe di attività dovrebbe estende l'AppCompatActivity
Spero che questo risposta è stata.
Impostazione del menu delle opzioni dopo aver creato la vista frammento ha funzionato bene per me.
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
setHasOptionsMenu(true);
}
Il mio problema era leggermente diverso. Ho fatto tutto bene. Ma ero ereditare la classe sbagliata per l'attività che ospita il frammento.
Quindi, per essere chiari, se modo si sostituisce onCreateOptionsMenu(Menu menu, MenuInflater inflater)
nel frammento, assicurarsi che la classe di attività che ospita questo eredita frammento android.support.v7.app.ActionBarActivity
(nel caso in cui si vorrebbe sostenere sotto il livello di API 11).
Sono stato ereditare la android.support.v4.app.FragmentActivity
al livello di supporto di API di sotto di 11.
Una cosa che vorrei aggiungere a questo e il motivo non funzionava per me.
E 'simile alla risposta di Napster.
-
Assicurati che l'attività di hosting del frammento si estende
AppCompatActivity
, nonFragmentActivity
!public class MainActivity extends AppCompatActivity { }
Dal Google Riferimento Documentazione per FragmentActivity:
. Nota: Se si desidera implementare un'attività che include una barra delle operazioni, si dovrebbe invece utilizzare la classe ActionBarActivity, che è una sottoclasse di questo, quindi consente di utilizzare Frammento API a livello di API 7 e superiori
-
Per aggiornare la risposta di Napster -.
ActionBarActivity
ora deprecato, usoAppCompatActivity
invece -
Quando si utilizza
AppCompatActivity
, anche assicurarsi di impostare "il toTheme.AppCompat
attività di tema o un tema simile" (Google Doc).
Nota: android.support.v7.app.AppCompatActivity
è una sottoclasse della classe android.support.v4.app.FragmentActivity
(vedi AppCompatActivity doc ref).
Nel menu cartella di rendere un file xml e .menu aggiungere questo xml
<item
android:id="@+id/action_search"
android:icon="@android:drawable/ic_menu_search"
android:title="@string/action_search"
app:actionViewClass="android.support.v7.widget.SearchView"
app:showAsAction="always|collapseActionView" />
Nella classe frammento overide questo metodo e
implement SearchView.OnQueryTextListener in your fragment class
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
setHasOptionsMenu(true);
}
Ora basta l'installazione di file menu XML in classe frammento
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.menu_main, menu);
final MenuItem item = menu.findItem(R.id.action_search);
final SearchView searchView = (SearchView)
MenuItemCompat.getActionView(item);
MenuItemCompat.setOnActionExpandListener(item,
new MenuItemCompat.OnActionExpandListener() {
@Override
public boolean onMenuItemActionCollapse(MenuItem item) {
// Do something when collapsed
return true; // Return true to collapse action view
}
@Override
public boolean onMenuItemActionExpand(MenuItem item) {
// Do something when expanded
return true; // Return true to expand action view
}
});
}
Se tutto quanto sopra non funziona, è necessario eseguire il debug e far funzionare sicuro onCreateOptionsMenu è stata chiamata (ponendo di debug o il registro di scrittura ...)
Se non gestito, forse il tema Android non sta sostenendo la barra delle azioni.
Apri AndroidManifest.xml e impostare il valore per android:theme
con bar a tema azione di sostegno :
<activity
android:name=".MainActivity"
android:label="@string/app_name"
android:theme="@style/Theme.AppCompat">
sul onCreate metodo add setHasOptionMenu ()
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
}
Poi di override onCreateOptionsMenu
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
menu.add("Menu item")
.setIcon(android.R.drawable.ic_delete)
.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
}