Come modificare l'icona MenuItem in ActionBar a livello di codice


122

Come modificare l'icona MenuItem in ActionBar a livello di codice? Ho provato a usare

MenuItem menuItem = (MenuItem)findViewById(R.id.action_settings);
menuItem.setIcon(getResources().getDrawable(R.drawable.ic_launcher))

ma non funziona. Questo è il mio codice:

Attività principale

package com.test;
import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;

public class MainActivity extends ActionBarActivity {
    private Button button;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        button = (Button)findViewById(R.id.button);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                MenuItem menuItem = (MenuItem)findViewById(R.id.action_settings);
                menuItem.setIcon(getResources().getDrawable(R.drawable.ic_launcher));
            }
        });
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {

        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        int id = item.getItemId();
        if (id == R.id.action_settings) {
            return true;
        }
        return super.onOptionsItemSelected(item);
    }
}

main.xml

<menu
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    tools:context=".MainActivity" >

    <item
        android:icon="@drawable/action_settings"
        android:id="@+id/action_settings"
        android:title="@string/action_settings"
        android:orderInCategory="100"
        app:showAsAction="always"/>
</menu>

activity_main

<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_height="fill_parent"
    android:layout_width="fill_parent">
    <Button
        android:id="@+id/button"
        android:text="Set icon"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />
</LinearLayout>

Questa è l'eccezione che ho avuto dopo aver eseguito:

MenuItem menuItem = (MenuItem)findViewById(R.id.action_settings);


11-09 19:52:40.471    1735-1735/com.test E/AndroidRuntime FATAL EXCEPTION: main
    java.lang.ClassCastException: android.support.v7.internal.view.menu.ActionMenuItemView
            at com.test.MainActivity$1.onClick(MainActivity.java:19)
            at android.view.View.performClick(View.java:2485)
            at android.view.View$PerformClick.run(View.java:9080)
            at android.os.Handler.handleCallback(Handler.java:587)
            at android.os.Handler.dispatchMessage(Handler.java:92)
            at android.os.Looper.loop(Looper.java:123)
            at android.app.ActivityThread.main(ActivityThread.java:3683)
            at java.lang.reflect.Method.invokeNative(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:507)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597)
            at dalvik.system.NativeStart.main(Native Method)

Risposte:


256

Non puoi usare findViewById () sulle voci di menu in onCreate () perché il layout del menu non è ancora gonfiato. È possibile creare una variabile Menu globale e inizializzarla in onCreateOptionsMenu () e quindi utilizzarla in onClick ().

private Menu menu;

Nel tuo onCreateOptionsMenu ()

this.menu = menu;

Nel metodo onClick () del tuo pulsante

menu.getItem(0).setIcon(ContextCompat.getDrawable(this, R.drawable.ic_launcher));

che dire di un frammento, dove non c'è onCreateOptionsMenu ()?
AlleyOOP

Probabilmente dovrai chiamare un metodo sulla tua attività dal frammento
Lalith Mohan

@ LalithMohan, ho provato la stessa cosa, ma non funziona. Potrei anche cambiare il colore del carattere del titolo della voce di menu, non sono in grado di cambiare l'icona. Ho inviato la mia domanda qui: stackoverflow.com/questions/36716450/...
Akeshwar Jha

1
Ho ricevuto il messaggio di errore "getDrawable () è deprecato". Le possibili soluzioni sono in questo thread: stackoverflow.com/questions/29041027/…
Alexey

getDrawable è deprecato. Qualcuno ha una nuova soluzione?
Solo

46

La risposta di Lalith è corretta.

Puoi anche provare questo approccio:

button.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            invalidateOptionsMenu();
        }
    });

 @Override
 public boolean onPrepareOptionsMenu(Menu menu) {

    MenuItem settingsItem = menu.findItem(R.id.action_settings);
    // set your desired icon here based on a flag if you like
    settingsItem.setIcon(ContextCompat.getDrawable(this, R.drawable.ic_launcher)); 

    return super.onPrepareOptionsMenu(menu);
 }

Questo è il modo per farlo. +1
lasec0203

8

Questo funziona per me. Dovrebbe essere nel tuo onOptionsItemSelected(MenuItem item)metodo item.setIcon(R.drawable.your_icon);


3

Ho risolto questo problema in questo modo:

In onCreateOptionsMenu:

this.menu = menu;
this.menu.add("calendar");
ImageView imageView = new ImageView(getActivity());
imageView.setMinimumHeight(128);
imageView.setMinimumWidth(128);
imageView.setImageDrawable(yourDrawable);
MenuItem item = this.menu.getItem(0);
item.setActionView(imageView);

in onOptionsItemSelected:

if (item.getOrder() == 0) {
    //TODO
    return true;
}

3

Invece di getViewById (), usa

MenuItem item = getToolbar().getMenu().findItem(Menu.FIRST);

sostituendo il Menu.FIRSTcon l'ID della voce di menu.


3

Ecco come ho risolto questo:

1 - crea una variabile di campo come: private Menu mMenuItem;

2 - sovrascrivi il metodo invalidateOptionsMenu ():

@Override
public void invalidateOptionsMenu() {
    super.invalidateOptionsMenu();
}

3 - chiama il metodo invalidateOptionsMenu()nel tuo fileonCreate()

4 - aggiungi il mMenuItem = menutuo onCreateOptionsMenu(Menu menu)come questo:

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.webview_menu, menu);
    mMenuItem = menu;
    return super.onCreateOptionsMenu(menu);
}

5 - nel metodo onOptionsItemSelected(MenuItem item)cambia l'icona che desideri in questo modo:

 @Override
public boolean onOptionsItemSelected(MenuItem item) {

    switch (item.getItemId()){

        case R.id.R.id.action_settings:
            mMenuItem.getItem(0).setIcon(R.drawable.ic_launcher); // to change the fav icon
            //Toast.makeText(this, " " + mMenuItem.getItem(0).getTitle(), Toast.LENGTH_SHORT).show(); <<--- this to check if the item in the index 0 is the one you are looking for
            return true;
    }
    return super.onOptionsItemSelected(item);
}

0

da usare in onMenuItemClick(MenuItem item) appena fareinvalidateOptionsMenu(); item.setIcon(ContextCompat.getDrawable(this, R.drawable.ic_baseline_play_circle_outline_24px));


0

Versione Kotlin:

toolbar.menu.findItem(R.id.notification).icon =
                    ContextCompat.getDrawable(requireContext(), R.drawable.ic_notification)

toolbar.menu.findItem(R.id.notification).isVisible = true

-1

Sta funzionando

      MenuItem tourchmeMenuItem; // Declare Global .......

 public boolean onCreateOptionsMenu(Menu menu) 
 {
        getMenuInflater().inflate(R.menu.search, menu);
        menu.findItem(R.id.action_search).setVisible(false);
        tourchmeMenuItem = menu.findItem(R.id.done);
        return true;
 }

    public boolean onOptionsItemSelected(MenuItem item) {

    case R.id.done:
                       if(LoginPreferences.getActiveInstance(CustomViewFinderScannerActivity.this).getIsFlashLight()){
                            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                                mScannerView.setFlash(false);
                                LoginPreferences.getActiveInstance(CustomViewFinderScannerActivity.this).setIsFlashLight(false);
                                tourchmeMenuItem.setIcon(getResources().getDrawable(R.mipmap.torch_white_32));
                            }
                        }else {
                            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                                mScannerView.setFlash(true);
                                LoginPreferences.getActiveInstance(CustomViewFinderScannerActivity.this).setIsFlashLight(true);
                                tourchmeMenuItem.setIcon(getResources().getDrawable(R.mipmap.torch_cross_white_32));
                            }
                        }
                        break;

}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.