Cách thay đổi biểu tượng MenuItem trong ActionBar theo lập trình


122

Làm cách nào để thay đổi biểu tượng MenuItem trong ActionBar theo lập trình? Tôi đã cố gắng sử dụng

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

nhưng nó không hoạt động. Đây là mã của tôi:

Hoạt động chủ yêu

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>

Đây là ngoại lệ mà tôi đã gặp phải sau khi chạy:

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)

Câu trả lời:


256

Bạn không thể sử dụng findViewById () trên các mục menu trong onCreate () vì bố cục menu chưa được phóng to. Bạn có thể tạo một biến Menu chung và khởi tạo nó trong onCreateOptionsMenu () và sau đó sử dụng nó trong onClick () của bạn.

private Menu menu;

Trong onCreateOptionsMenu () của bạn

this.menu = menu;

Trong phương thức onClick () của nút của bạn

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

Còn trong một phân đoạn, nơi không có onCreateOptionsMenu () thì sao?
AlleyOOP

Bạn có thể cần phải gọi một phương thức trên hoạt động của bạn từ Fragment của bạn
Lalith Mohan

@LalithMohan, tôi đã thử điều tương tự, nhưng nó không hoạt động. Mặc dù vậy, tôi có thể thay đổi màu phông chữ của tiêu đề mục menu, tôi không thể thay đổi biểu tượng. Tôi đã đăng câu hỏi của mình ở đây: stackoverflow.com/questions/36716450/…
Akeshwar Jha

1
Tôi nhận được thông báo lỗi "getDrawable () không được dùng nữa". Các giải pháp có thể có trong chủ đề này: stackoverflow.com/questions/29041027/…
Alexey

getDrawable không được dùng nữa. Có ai có giải pháp mới không?
Solo

46

Câu trả lời của Lalith là đúng.

Bạn cũng có thể thử cách tiếp cận này:

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

Đây là cách để làm điều đó. +1
lasec0203

8

Điều này làm việc cho tôi. Nó phải nằm trong onOptionsItemSelected(MenuItem item)phương pháp của bạnitem.setIcon(R.drawable.your_icon);


3

Tôi đã giải quyết vấn đề này theo cách này:

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

trong onOptionsItemSelected:

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

3

Thay vì getViewById (), hãy sử dụng

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

thay thế Menu.FIRSTbằng id mục menu của bạn.


3

Đây là cách tôi giải quyết vấn đề này:

1 - tạo một Biến trường như: private Menu mMenuItem;

2 - ghi đè phương thức validateOptionsMenu ():

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

3 - gọi phương thức invalidateOptionsMenu()trongonCreate()

4 - thêm mMenuItem = menuvào onCreateOptionsMenu(Menu menu)như thế này của bạn :

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

5 - trong phương thức onOptionsItemSelected(MenuItem item)thay đổi biểu tượng bạn muốn như sau:

 @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

để sử dụng trong onMenuItemClick(MenuItem item) chỉ làminvalidateOptionsMenu(); item.setIcon(ContextCompat.getDrawable(this, R.drawable.ic_baseline_play_circle_outline_24px));


0

Phiên bản Kotlin:

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

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

-1

Hoạt động của nó

      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;

}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.