Menú de opciones de Android en fragmento
-
25-10-2019 - |
Pregunta
Estoy tratando de agregar un elemento al menú Opciones de un grupo de fragmentos.
He creado un nuevo MenuFragment
clase y extendí esto para los fragmentos en los que deseo incluir el elemento del menú. Aquí está el código:
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);
}
}
Por alguna razón el onCreateOptionsMenu
parece no correr.
Solución
Llame al súper método:
@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);
}
Coloque las declaraciones de registro en el código para ver si no se llama el método o si el menú no está siendo modificado por su código.
También asegúrate de llamar setHasOptionsMenu(boolean)
en onCreate(Bundle)
Para notificar al fragmento que debe participar en el manejo del menú de opciones.
Otros consejos
Tuve el mismo problema, pero creo que es mejor resumir e introducir el último paso para que funcione:
Agregue el método SethasoptionsMenu (verdadero) en su fragmento
onCreate(Bundle savedInstanceState)
método.Anular
onCreateOptionsMenu(Menu menu, MenuInflater inflater)
(Si quieres hacer algo diferente en el menú de tu fragmento) yonOptionsItemSelected(MenuItem item)
Métodos en su fragmento.Dentro de tu
onOptionsItemSelected(MenuItem item)
Método de la actividad, asegúrese de devolver falso cuando la acción del elemento del menú se implementaría enonOptionsItemSelected(MenuItem item)
Método del fragmento.
Un ejemplo:
Actividad
@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;
}
Fragmento
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 encuentras el onCreateOptionsMenu(Menu menu, MenuInflater inflater)
El método no se está invocando, asegúrese de llamar a lo siguiente desde el fragmento onCreate(Bundle savedInstanceState)
método:
setHasOptionsMenu(true)
Si necesitas un menu
Para refrescar un webview
dentro de un específico Fragment
, puedes usar:
Fragmento:
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;
}
menú.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>
En el menu.xml
Debe agregar todos los elementos del menú. Luego puede ocultar elementos que no desea ver en la carga inicial.
menú.xml
<item
android:id="@+id/action_newItem"
android:icon="@drawable/action_newItem"
android:showAsAction="never"
android:visible="false"
android:title="@string/action_newItem"/>
Agregar setHasOptionsMenu(true)
En el método OnCreate () para invocar los elementos del menú en su clase de fragmento.
Fragmentclass.java
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
}
No necesitas anular onCreateOptionsMenu
en tu clase de fragmento de nuevo. Los elementos del menú se pueden cambiar (agregar/eliminar) anulando onPrepareOptionsMenu
Método disponible en fragmento.
@Override
public void onPrepareOptionsMenu(Menu menu) {
menu.findItem(R.id.action_newItem).setVisible(true);
super.onPrepareOptionsMenu(menu);
}
Tl; Dr
Utilizar el android.support.v7.widget.Toolbar
Y solo haz:
toolbar.inflateMenu(R.menu.my_menu)
toolbar.setOnMenuItemClickListener {
onOptionsItemSelected(it)
}
Barra de herramientas independiente
La mayoría de las soluciones sugeridas como setHasOptionsMenu(true)
solo funcionan cuando el La actividad de los padres tiene la barra de herramientas en su diseño y lo declara a través de setSupportActionBar()
. Entonces los fragmentos pueden participar en la población de menú de esta exacto Barra de acciones:
Fragment.OncreAteeCtionsMenu (): Inicialice el contenido del menú de opciones estándar del host del fragmento.
Si desea una barra de herramientas independiente y un menú para un fragmento específico Puedes hacer lo siguiente:
menú_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í, es tan fácil. Ni siquiera necesitas anular onCreate()
o onCreateOptionsMenu()
.
PD: Esto solo funciona con android.support.v4.app.Fragment
y android.support.v7.widget.Toolbar
(también asegú (asegúrese de usar AppCompatActivity
y un AppCompat
tema en tu styles.xml
).
Debe usar menú.clear () antes de inflar los menús.
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
menu.clear();
inflater.inflate(R.menu.menu, menu);
super.onCreateOptionsMenu(menu, inflater);
}
y
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
}
En mi caso, aquí están los pasos.
Paso 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);
}
Paso 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);
}
Paso 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 desea agregar su menú personalizado
@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);
}
He tenido el mismo problema, mis fragmentos eran páginas de una vie a la vista. La razón por la que estaba sucediendo es que estaba usando el gerente de fragmentos infantiles en lugar del gerente de fragmentos de apoyo de la actividad al instancias de FragmentPagerAdapter.
Archivo de menú:
<?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>
Código de actividad:
@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;
}
Código de fragmento:
@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;
}
Tu código está bien. Solo faltaba el Super en el método:
@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);
}
Me estaba volviendo loco porque ninguna de las respuestas aquí funcionó para mí.
Para mostrar el menú, tuve que llamar: setSupportActionBar(toolbar)
¡Hecho!
Nota: Si tu toolbar
La vista no está en el mismo diseño de actividad, no puede usar la llamada anterior directamente desde su clase de actividad, en este caso deberá obtener esa actividad de su clase de fragmento y luego llamar al setSupportActionBar(toolbar)
. Recordando: su clase de actividad debe extender la Apocompatactividad.
Espero que esta respuesta te ayude.
Configurar el menú de opciones después de crear la vista de fragmentos funcionó bien para mí.
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
setHasOptionsMenu(true);
}
Mi problema era ligeramente diferente. Hice todo bien. Pero estaba heredando la clase equivocada para la actividad que alojaba el fragmento.
Entonces, para ser claros, si estás anulando onCreateOptionsMenu(Menu menu, MenuInflater inflater)
En el fragmento, asegúrese de que su clase de actividad que alberga este fragmento hereda android.support.v7.app.ActionBarActivity
(En caso de que desee admitir por debajo del nivel de API 11).
Estaba heredando el android.support.v4.app.FragmentActivity
para admitir el nivel de API por debajo de 11.
Una cosa que agregaría a esto y la razón por la que no estaba funcionando para mí.
Es similar a la respuesta de Napster.
Asegúrese de que la actividad de alojamiento de su fragmento se extienda
AppCompatActivity
, noFragmentActivity
!public class MainActivity extends AppCompatActivity { }
De la referencia de Google Documentación Para la fragmentación de la actividad:
Nota: Si desea implementar una actividad que incluya una barra de acción, debe usar la clase ActionBaractivity, que es una subclase de esta, por lo que le permite usar API de fragmentos en el nivel API de API y superior.
Para actualizar la respuesta de Napster -
ActionBarActivity
ahora estar en desuso, usarAppCompatActivity
en cambio.Cuando usas
AppCompatActivity
, también asegúrese de establecer "el tema de la actividad paraTheme.AppCompat
o un tema similar "(Google Doc).
Nota: android.support.v7.app.AppCompatActivity
es una subclase del android.support.v4.app.FragmentActivity
Clase (ver Apompatactividad Ref Doc).
En su carpeta de menú, haga un archivo .menu xml y agregue este 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" />
En su clase de fragmento en exceso de este método y
implement SearchView.OnQueryTextListener in your fragment class
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
setHasOptionsMenu(true);
}
Ahora solo configure su archivo XML de menú en la clase de fragmento
@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 todo lo anterior no funciona, debe depurar y asegurarse de que se haya llamado a la función que se ha llamado (colocando el registro de depuración o escritura ...)
Si no se ejecuta, tal vez su tema de Android no es compatible con la barra de acción.Abra androidManifest.xml y establezca el valor para android:theme
con Temo Support Action Bar:
<activity
android:name=".MainActivity"
android:label="@string/app_name"
android:theme="@style/Theme.AppCompat">
en tu abatimiento Método Agregar sethasoptionmenu ()
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
}
Después anular su OnCreateeCtionsMenu
@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);
}