So ändern Sie das MenuItem-Symbol in ActionBar programmgesteuert

121

Wie ändere ich das MenuItem-Symbol in ActionBar programmgesteuert? Ich habe versucht zu benutzen

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

aber es funktioniert nicht. Das ist mein Code:

Hauptaktivität

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>

Dies ist die Ausnahme, die ich nach dem Laufen hatte:

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)
Venenhorn
quelle

Antworten:

255

Sie können findViewById () nicht für Menüelemente in onCreate () verwenden, da das Menülayout noch nicht aufgeblasen ist. Sie können eine globale Menüvariable erstellen und im onCreateOptionsMenu () initialisieren und dann in Ihrem onClick () verwenden.

private Menu menu;

In Ihrem onCreateOptionsMenu ()

this.menu = menu;

In der onClick () -Methode Ihrer Schaltfläche

menu.getItem(0).setIcon(ContextCompat.getDrawable(this, R.drawable.ic_launcher));
Lalith Mohan
quelle
Was ist mit einem Fragment, in dem es kein onCreateOptionsMenu () gibt?
AlleyOOP
Sie müssen wahrscheinlich eine Methode für Ihre Aktivität aus Ihrem Fragment
aufrufen
@LalithMohan, ich habe das gleiche versucht, aber es funktioniert nicht. Ich könnte zwar die Schriftfarbe des Titels des Menüelements ändern, aber ich kann das Symbol nicht ändern. Ich habe meine Frage hier gepostet: stackoverflow.com/questions/36716450/…
Akeshwar Jha
1
Ich habe die Fehlermeldung "getDrawable () ist veraltet" erhalten. Mögliche Lösungen finden Sie in diesem Thread: stackoverflow.com/questions/29041027/…
Alexey
getDrawable ist veraltet. Hat jemand eine neue Lösung?
Solo
46

Laliths Antwort ist richtig.

Sie können auch diesen Ansatz ausprobieren:

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);
 }
Marius
quelle
Dies ist der Weg, um es zu tun. +1
lasec0203
8

Das funktioniert bei mir. Es sollte in Ihrer onOptionsItemSelected(MenuItem item)Methode sein item.setIcon(R.drawable.your_icon);

Mohale
quelle
3

Ich habe dieses Problem folgendermaßen gelöst:

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;
}
iamthevoid
quelle
3

Verwenden Sie anstelle von getViewById ()

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

Ersetzen Sie die Menu.FIRSTdurch Ihre Menüpunkt-ID.

Alen Siljak
quelle
3

Hier ist, wie ich das gelöst habe:

1 - Erstellen Sie eine Feldvariable wie: private Menu mMenuItem;

2 - Überschreiben Sie die Methode invalidateOptionsMenu ():

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

3 - Rufen Sie die Methode invalidateOptionsMenu()in Ihrem aufonCreate()

4 - fügen mMenuItem = menuSie onCreateOptionsMenu(Menu menu)Folgendes hinzu:

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

5 - onOptionsItemSelected(MenuItem item)Ändern Sie in der Methode das gewünschte Symbol wie folgt:

 @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);
}
korchix
quelle
0

in onMenuItemClick(MenuItem item) nur tun zu verwendeninvalidateOptionsMenu(); item.setIcon(ContextCompat.getDrawable(this, R.drawable.ic_baseline_play_circle_outline_24px));

Splhead
quelle
0

Kotlin-Version:

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

toolbar.menu.findItem(R.id.notification).isVisible = true
SpiralDev
quelle
-1

Es funktioniert

      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;

}
Keshav Gera
quelle