Bagaimana mengubah ikon MenuItem di ActionBar secara terprogram

122

Bagaimana cara mengubah ikon MenuItem di ActionBar secara terprogram? Saya mencoba menggunakan

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

tapi tidak berhasil. Ini kode saya:

Aktifitas utama

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>

Ini adalah pengecualian yang saya miliki setelah menjalankan:

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)
veinhorn
sumber

Jawaban:

256

Anda tidak bisa menggunakan findViewById () pada item menu di onCreate () karena tata letak menu belum melambung. Anda bisa membuat variabel Menu global dan menginisialisasinya di onCreateOptionsMenu () dan kemudian menggunakannya di onClick ().

private Menu menu;

Di onCreateOptionsMenu () Anda

this.menu = menu;

Dalam metode onClick () tombol Anda

menu.getItem(0).setIcon(ContextCompat.getDrawable(this, R.drawable.ic_launcher));
Lalith Mohan
sumber
bagaimana dengan sebuah fragmen, yang tidak memiliki onCreateOptionsMenu ()?
AlleyOOP
Anda mungkin perlu memanggil metode Aktivitas dari Fragmen Anda
Lalith Mohan
@LalithMohan, saya mencoba hal yang sama, tetapi tidak berhasil. Meskipun saya dapat mengubah warna font dari judul item menu, saya tidak dapat mengubah ikon. Saya telah memposting pertanyaan saya di sini: stackoverflow.com/questions/36716450/…
Akeshwar Jha
1
Saya mendapat pesan kesalahan "getDrawable () tidak digunakan lagi". Solusi yang mungkin ada di utas ini: stackoverflow.com/questions/29041027/…
Alexey
getDrawable tidak digunakan lagi. Ada yang punya solusi baru?
Solo
46

Jawaban Lalith benar.

Anda juga dapat mencoba pendekatan ini:

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
sumber
Inilah cara melakukannya. +1
lasec0203
8

Ini berhasil untuk saya. Itu harus sesuai dengan onOptionsItemSelected(MenuItem item)metode Andaitem.setIcon(R.drawable.your_icon);

Mohale
sumber
3

Saya menyelesaikan masalah ini dengan cara ini:

Masuk 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);

di onOptionsItemSelected:

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

Sebagai ganti getViewById (), gunakan

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

mengganti Menu.FIRSTdengan id item menu Anda.

Alen Siljak
sumber
3

Inilah cara saya menyelesaikan ini:

1 - buat Variabel Bidang seperti: private Menu mMenuItem;

2 - timpa metode invalidateOptionsMenu ():

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

3 - panggil metode invalidateOptionsMenu()dionCreate()

4 - tambahkan mMenuItem = menudi Anda onCreateOptionsMenu(Menu menu)seperti ini:

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

5 - dalam metode ini onOptionsItemSelected(MenuItem item)ubah ikon yang Anda inginkan seperti ini:

 @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.dll
sumber
0

untuk digunakan di onMenuItemClick(MenuItem item) lakukan sajainvalidateOptionsMenu(); item.setIcon(ContextCompat.getDrawable(this, R.drawable.ic_baseline_play_circle_outline_24px));

splhead
sumber
0

Versi Kotlin:

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

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

Bekerja

      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
sumber