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.

¿Fue útil?

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:

  1. Agregue el método SethasoptionsMenu (verdadero) en su fragmento onCreate(Bundle savedInstanceState) método.

  2. Anular onCreateOptionsMenu(Menu menu, MenuInflater inflater) (Si quieres hacer algo diferente en el menú de tu fragmento) y onOptionsItemSelected(MenuItem item) Métodos en su fragmento.

  3. 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 en onOptionsItemSelected(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 onPrepareOptionsMenuMé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.

  1. Asegúrese de que la actividad de alojamiento de su fragmento se extienda AppCompatActivity, no FragmentActivity!

    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.

  2. Para actualizar la respuesta de Napster - ActionBarActivity ahora estar en desuso, usar AppCompatActivity en cambio.

  3. 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);
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top