J'essaie d'ajouter un élément au menu d'options à partir d'un groupe de fragments.
J'ai créé une nouvelle classe MenuFragment
et l'ai étendue pour les fragments dans lesquels je souhaite inclure l'élément de menu. Voici le code:
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);
}
}
Pour une raison quelconque, la onCreateOptionsMenu
ne semble pas fonctionner.
Appelez la super méthode:
@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);
}
Mettez des instructions de journal dans le code pour voir si la méthode n'est pas appelée ou si le menu n'est pas modifié par votre code.
Assurez-vous également que vous appelez setHasOptionsMenu(boolean)
dans onCreate(Bundle)
pour indiquer au fragment qu'il doit participer à la gestion du menu d'options.
J'ai eu le même problème, mais je pense qu'il est préférable de résumer et d'introduire la dernière étape pour le faire fonctionner:
Ajoutez la méthode setHasOptionsMenu (true) dans la méthode onCreate(Bundle savedInstanceState)
de votre fragment.
Remplacez onCreateOptionsMenu(Menu menu, MenuInflater inflater)
(si vous voulez faire quelque chose de différent dans le menu de votre Fragment) et onOptionsItemSelected(MenuItem item)
méthodes dans votre Fragment.
Dans la méthode de votre onOptionsItemSelected(MenuItem item)
Activity, assurez-vous de renvoyer false lorsque l'action de l'élément de menu serait implémentée dans la méthode de onOptionsItemSelected(MenuItem item)
Fragment.
Un exemple:
Activité
@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;
}
Fragment
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;
}
Si vous trouvez que la méthode onCreateOptionsMenu(Menu menu, MenuInflater inflater)
n'est pas appelée, assurez-vous d'appeler ce qui suit à partir de la méthode onCreate(Bundle savedInstanceState)
du fragment:
setHasOptionsMenu(true)
Si vous avez besoin d'un menu
pour actualiser un webview
à l'intérieur d'un Fragment
spécifique, vous pouvez utiliser:
fragment:
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 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>
Dans le menu.xml
, vous devez ajouter tous les éléments de menu. Vous pouvez ensuite masquer les éléments que vous ne souhaitez pas voir lors du chargement initial.
menu.xml
<item
Android:id="@+id/action_newItem"
Android:icon="@drawable/action_newItem"
Android:showAsAction="never"
Android:visible="false"
Android:title="@string/action_newItem"/>
Ajoutez setHasOptionsMenu(true)
dans la méthode onCreate () pour appeler les éléments de menu de votre classe Fragment.
FragmentClass.Java
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
}
Vous n'avez pas besoin de redéfinir onCreateOptionsMenu
dans votre classe Fragment. Les éléments de menu peuvent être modifiés (Ajouter/Supprimer) en remplaçant la méthode onPrepareOptionsMenu
disponible dans Fragment.
@Override
public void onPrepareOptionsMenu(Menu menu) {
menu.findItem(R.id.action_newItem).setVisible(true);
super.onPrepareOptionsMenu(menu);
}
Vous devez utiliser menu.clear () avant de gonfler les menus.
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
menu.clear();
inflater.inflate(R.menu.menu, menu);
super.onCreateOptionsMenu(menu, inflater);
}
et
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
}
Utilisez le Android.support.v7.widget.Toolbar
et faites simplement:
toolbar.inflateMenu(R.menu.my_menu)
toolbar.setOnMenuItemClickListener {
onOptionsItemSelected(it)
}
La plupart des solutions suggérées telles que setHasOptionsMenu(true)
ne fonctionnent que lorsque l'activité parent a la barre d'outils dans sa présentation et la déclare via setSupportActionBar()
. Ensuite, les fragments peuvent participer au menu population de cette ActionBar exacte :
Fragment.onCreateOptionsMenu (): initialise le contenu du menu d'options standard du Fragment Host.
Si vous voulez une barre d’outils autonome et un menu pour un fragment spécifique vous pouvez faire ce qui suit:
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)
}
}
Oui, c'est aussi simple que ça. Vous n'avez même pas besoin de remplacer onCreate()
ou onCreateOptionsMenu()
.
PS: Ceci ne fonctionne qu'avec Android.support.v4.app.Fragment
et Android.support.v7.widget.Toolbar
(veillez également à utiliser AppCompatActivity
et un thème AppCompat
dans votre styles.xml
).
Dans mon cas, voici les étapes.
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Here notify the fragment that it should participate in options menu handling.
setHasOptionsMenu(true);
}
@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);
}
@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);
}
Si vous voulez ajouter votre menu personnalisé
@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);
}
J'ai eu le même problème, mes fragments étaient des pages d'un ViewPager. La raison en était que j'utilisais le gestionnaire de fragments enfant plutôt que le gestionnaire de fragments de support d'activité lors de l'instanciation de FragmentPagerAdapter.
Votre code est bon. Il ne manquait que le super dans la méthode:
@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);
}
Fichier de 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>
Code d'activité:
@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;
}
Code de fragment:
@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;
}
Je devenais fou parce qu'aucune des réponses ici ne fonctionnait pour moi.
Pour afficher le menu, j'ai dû appeler:setSupportActionBar(toolbar)
Terminé!
Remarque: si votre vue toolbar
ne se trouve pas dans la même structure d'activité, vous ne pouvez pas utiliser l'appel ci-dessus directement à partir de votre classe d'activité. Dans ce cas, vous devez extraire cette activité de votre classe de fragment, puis appeler la setSupportActionBar(toolbar)
. Rappel: votre classe d'activité devrait étendre AppCompatActivity.
J'espère que cette réponse vous aidera.
La définition du menu des options après la création de la vue fragmentée a bien fonctionné pour moi.
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
setHasOptionsMenu(true);
}
Dans votre dossier de menu, créez un fichier .menu xml et ajoutez-le. 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" />
Dans votre classe de fragment, passez outre cette méthode et
implement SearchView.OnQueryTextListener in your fragment class
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
setHasOptionsMenu(true);
}
Maintenant, configurez votre fichier xml de menu dans la classe fragment
@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
}
});
}
Mon problème était légèrement différent. J'ai tout fait correctement. Mais j'héritais de la mauvaise classe pour l'activité hébergeant le fragment.
En clair, si vous écrasez onCreateOptionsMenu(Menu menu, MenuInflater inflater)
dans le fragment, assurez-vous que votre classe d'activité hébergeant ce fragment hérite de Android.support.v7.app.ActionBarActivity
(au cas où vous souhaiteriez prendre en charge un niveau inférieur à l'API 11).
J'héritais du Android.support.v4.app.FragmentActivity
pour prendre en charge un niveau d'API inférieur à 11.
Une chose que je voudrais ajouter à cela et la raison pour laquelle cela ne fonctionnait pas pour moi.
Cela ressemble à la réponse de Napster.
Assurez-vous que l'activité d'hébergement de votre fragment s'étend AppCompatActivity
et non FragmentActivity
!
public class MainActivity extends AppCompatActivity {
}
De la référence Google Documentation pour FragmentActivity:
Remarque: Si vous souhaitez implémenter une activité comprenant une barre d'actions, vous devez plutôt utiliser la classe ActionBarActivity, qui est une sous-classe de celle-ci, vous permettant ainsi d'utiliser les API de fragmentation à partir du niveau 7.
Pour mettre à jour la réponse de Napster - ActionBarActivity
maintenant obsolète, utilisez plutôt AppCompatActivity
.
Lorsque vous utilisez AppCompatActivity
, veillez également à définir "le thème de l'activité toTheme.AppCompat
ou un thème similaire" (Google Doc).
Remarque: Android.support.v7.app.AppCompatActivity
est une sous-classe de la classe Android.support.v4.app.FragmentActivity
(voir AppCompatActivity ref doc).
Si tout ce qui précède ne fonctionne pas, vous devez déboguer et vous assurer que la fonction onCreateOptionsMenu a été appelée (en plaçant le journal de débogage ou d'écriture ...)
S'il n'est pas exécuté, votre thème Android ne prend peut-être pas en charge la barre d'action. Ouvrez AndroidManifest.xml et définissez la valeur pour Android:theme
avec la barre d'action de prise en charge de thème:
<activity
Android:name=".MainActivity"
Android:label="@string/app_name"
Android:theme="@style/Theme.AppCompat">
sur votre méthode onCreate, ajoutez setHasOptionMenu ()
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
}
Alors annulation votre onCreateOptionsMen
@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);
}