Menu Android Options dans Fragment
-
25-10-2019 - |
Question
Je suis en train d'ajouter un élément au menu d'options à partir d'un groupe de fragments.
J'ai créé une nouvelle classe MenuFragment
et étendu ce pour les fragments que 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 le onCreateOptionsMenu
ne semble pas courir.
La solution
Appelez le 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);
}
Mettre les déclarations du journal dans le code pour voir si la méthode n'est pas appelé ou si le menu est pas modifié par votre code.
Assurez-vous également que vous appelez setHasOptionsMenu(boolean)
dans onCreate(Bundle)
de notifier le fragment qu'il devrait participer à ses options de gestion du menu.
Autres conseils
J'ai eu le même problème, mais je pense qu'il est préférable de résumer et de présenter la dernière étape pour le faire fonctionner:
-
Ajouter setHasOptionsMenu (true) dans votre méthode de
onCreate(Bundle savedInstanceState)
de Fragment. -
Remplacer
onCreateOptionsMenu(Menu menu, MenuInflater inflater)
(si vous voulez faire quelque chose de différent dans votre menu de Fragment) et les méthodes deonOptionsItemSelected(MenuItem item)
dans votre Fragment. -
Dans votre méthode de l'activité de
onOptionsItemSelected(MenuItem item)
, assurez-vous return false lorsque l'action de l'élément de menu sera mis en œuvre dans la méthode deonOptionsItemSelected(MenuItem item)
Fragment.
Exemple Un:
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 la méthode onCreateOptionsMenu(Menu menu, MenuInflater inflater)
n'est pas invoqué, assurez-vous que vous appelez ce qui suit de la méthode de onCreate(Bundle savedInstanceState)
de Fragment:
setHasOptionsMenu(true)
Si vous avez besoin d'un menu
pour rafraîchir un webview
dans 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.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>
Dans le menu.xml
vous devez ajouter tous les éléments du menu. Ensuite, vous pouvez masquer les éléments que vous ne voulez pas voir dans le 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"/>
Ajouter setHasOptionsMenu(true)
dans la méthode onCreate () pour appeler les éléments de menu dans votre classe Fragment.
FragmentClass.java
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
}
Vous ne devez remplacer onCreateOptionsMenu
dans votre classe Fragment à nouveau. Les éléments de menu peuvent être modifiés (Ajout / suppression) en surchargeant onPrepareOptionsMenu
method disponible en Fragment.
@Override
public void onPrepareOptionsMenu(Menu menu) {
menu.findItem(R.id.action_newItem).setVisible(true);
super.onPrepareOptionsMenu(menu);
}
TL; DR
Utilisez le android.support.v7.widget.Toolbar
et faire juste:
toolbar.inflateMenu(R.menu.my_menu)
toolbar.setOnMenuItemClickListener {
onOptionsItemSelected(it)
}
Barre d'outils autonome
La plupart des solutions proposées comme setHasOptionsMenu(true)
ne travaillent que lorsque l'activité mère a la barre d'outils dans sa mise en page et déclare via setSupportActionBar()
. Ensuite, les fragments peuvent participer à la population de menu de cette exacte ActionBar :
Fragment.onCreateOptionsMenu ():. Initialiser Le contenu du menu des options standard de l'hôte Fragment
Si vous voulez une barre d'outils autonome et le menu pour un spécifique Fragment vous pouvez effectuer les opérations suivantes:
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, il est facile. Vous ne même pas besoin de surcharger onCreate()
ou onCreateOptionsMenu()
.
PS:. Ce ne travaille avec android.support.v4.app.Fragment
et android.support.v7.widget.Toolbar
(aussi être sûr d'utiliser AppCompatActivity
et un thème de AppCompat
dans votre styles.xml
)
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);
}
Dans mon cas, voici les étapes.
Etape-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);
}
Etape-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);
}
Etape-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);
}
Si vous voulez ajouter votre commande de menu
@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 les pages d'un ViewPager. La raison pour laquelle il se passait que j'utilisais gestionnaire de fragments d'enfant plutôt que le gestionnaire de fragments de soutien à l'activité lors de l'instanciation FragmentPagerAdapter.
Menu Fichier:
<?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;
}
Fragment de code:
@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;
}
Votre code est très bien. Seul le super était absent 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);
}
Je devenais fou, car aucun des réponses ici a fonctionné pour moi.
Pour afficher le menu que je devais appeler: setSupportActionBar(toolbar)
Fait!
Note: si votre vue toolbar
est pas dans la même mise en page d'activité que vous ne pouvez pas utiliser l'appel ci-dessus directement à partir de votre classe d'activité, dans ce cas, vous aurez besoin d'obtenir que l'activité de votre classe de fragments puis appelez le setSupportActionBar(toolbar)
. Se souvenir:. Votre classe d'activité devrait Prolonge la AppCompatActivity
L'espoir que cette réponse vous aide.
Réglage du menu d'options après avoir créé la vue fragment a bien fonctionné pour moi.
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
setHasOptionsMenu(true);
}
Mon problème était légèrement différent. Je l'ai fait tout droit. Mais je héritant de la mauvaise classe pour l'activité d'hébergement du fragment.
Donc, pour être clair, si vous surchargez onCreateOptionsMenu(Menu menu, MenuInflater inflater)
dans le fragment, assurez-vous que votre classe d'activité qui hôtes ce fragment hérite android.support.v7.app.ActionBarActivity
(dans le cas où vous voudriez soutenir en dessous du niveau de l'API 11).
Je héritait du android.support.v4.app.FragmentActivity
au niveau de l'API de soutien ci-dessous 11.
Une chose que je voudrais ajouter à cela et la raison pour laquelle il ne fonctionnait pas pour moi.
Il est similaire à la réponse de Napster.
-
Assurez-vous que l'activité d'hébergement de votre fragment étend
AppCompatActivity
, pasFragmentActivity
!public class MainActivity extends AppCompatActivity { }
De la documentation de référence Google pour FragmentActivity:
Remarque:. Si vous voulez mettre en œuvre une activité qui comprend une barre d'action, vous devriez plutôt utiliser la classe ActionBarActivity, qui est une sous-classe de celui-ci, vous permet d'utiliser des API Fragment au niveau de l'API 7 et plus
-
Pour mettre à jour la réponse de Napster -.
ActionBarActivity
maintenant dépréciée, utilisezAppCompatActivity
à la place -
Lors de l'utilisation
AppCompatActivity
, aussi assurez-vous que vous définissez "le thème de l'activité toTheme.AppCompat
ou un thème similaire" (Google Doc).
Note: android.support.v7.app.AppCompatActivity
est une sous-classe de la classe android.support.v4.app.FragmentActivity
(voir AppCompatActivity ref doc).
dossier faire dans votre menu un fichier xml .menu et ajoutez ce 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 fragment overide 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 que la configuration de votre menu fichier xml en 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
}
});
}
Si tous les ci-dessus ne fonctionne pas, vous avez besoin de déboguer et assurez-vous que la fonction onCreateOptionsMenu a été appelé (en plaçant journal de débogage ou d'écriture ...)
Si ce n'est pas exécuté, peut-être votre thème Android ne supporte pas la barre d'action.
Ouvrir AndroidManifest.xml et définissez la valeur pour android:theme
avec barre d'action de soutien à thème :
<activity
android:name=".MainActivity"
android:label="@string/app_name"
android:theme="@style/Theme.AppCompat">
onCreate méthode add setHasOptionMenu ()
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
}
Alors 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);
}