Android:如何在按钮单击时启用/禁用选项菜单项?

Vik*_*kas 116 android contextmenu menuitem

我在使用onCreateOptionsMenu或使用onOptionsItemSelected方法时可以轻松完成.

但是我在屏幕的某处有一个按钮,点击该按钮时,它应该启用/禁用上下文菜单项.

Vik*_*kas 257

无论如何,文档涵盖了所有的东西.

在运行时更改菜单项

一旦创建了活动,该 onCreateOptionsMenu()方法仅被调用一次,如上所述.系统会保留并重新使用Menu您在此方法中定义的内容,直到您的活动被销毁.如果要在首次创建后随时更改"选项菜单",则必须覆盖该onPrepareOptionsMenu()方法.这会传递Menu对象,因为它当前存在.如果您要根据应用程序的当前状态删除,添加,禁用或启用菜单项,这将非常有用.

例如

@Override
public boolean onPrepareOptionsMenu (Menu menu) {
    if (isFinalized) {
        menu.getItem(1).setEnabled(false);
        // You can also use something like:
        // menu.findItem(R.id.example_foobar).setEnabled(false);
    }
    return true;
}
Run Code Online (Sandbox Code Playgroud)

在Android 3.0及更高版本中,当操作栏中显示菜单项时,选项菜单被视为始终打开.当事件发生并且您想要执行菜单更新时,您必须调用invalidateOptionsMenu()以请求系统调用onPrepareOptionsMenu().

  • 快速提示:返回`false`以完全禁用菜单. (16认同)
  • 另外,关于onPrepareOptionsMenu的API注释明确指出:派生类应始终(!)调用基类实现.你忘记了那里的超级电话. (5认同)
  • `setEnable()`确实会改变当你按下这个菜单时会发生什么,但不会改变它的外观(Android开发人员怎么了?).所以禁用*和*更改标题更清楚,或者最好只是让'MenuItem'不可见. (2认同)

Fra*_*ank 60

在所有Android版本中,最简单的方法:使用此方法将菜单操作图标显示为已禁用并将其设置为已禁用FUNCTION:

@Override
public boolean onPrepareOptionsMenu(Menu menu) {

    MenuItem item = menu.findItem(R.id.menu_my_item);

    if (myItemShouldBeEnabled) {
        item.setEnabled(true);
        item.getIcon().setAlpha(255);
    } else {
        // disabled
        item.setEnabled(false);
        item.getIcon().setAlpha(130);
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 我不是将alpha设置为0,而是设置为130. (8认同)
  • 取决于按钮的上下文.如果按钮通常服务的功能在当前状态下完全无法使用,那么可见性应该是不可见/不可用的.但是,如果按钮通常可以提供的功能可以在任何原因下使用(例如,如果用户成为高级会员,如果用户登录,如果用户连接到互联网等),那么将其显示为灰色是很好的因为它让用户知道他们出于某种原因无法访问某些现有功能. (8认同)
  • 在几乎所有用例中,将图标设置为不可见并不是更好.如果你有一个团队,他们会更好地留在他们的位置,并且灰色表示用户可以在某个程序状态下启用一个选项.使事物看不见和不可见,并可能导致布局变化是非常愚蠢的.大多数菜单会使项目变灰并且根据模式不删除它们是有原因的. (6认同)

小智 41

您可以在创建选项菜单时将项目另存为变量,然后随意更改其属性.

private MenuItem securedConnection;
private MenuItem insecuredConnection;

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    MenuInflater inflater = getMenuInflater();
    inflater.inflate(R.menu.connect_menu, menu);
    securedConnection = menu.getItem(0);
    insecuredConnection =  menu.getItem(1);
    return true;
}

public void foo(){
       securedConnection.setEnabled(true);
}    
Run Code Online (Sandbox Code Playgroud)

  • 我试过这个,但它不起作用.你是说`onPrepareOptionsMenu`吗? (2认同)

Kos*_*mad 6

简化@Vikas版本

@Override
public boolean onPrepareOptionsMenu (Menu menu) {

    menu.findItem(R.id.example_foobar).setEnabled(isFinalized);
    return true;
}
Run Code Online (Sandbox Code Playgroud)


Gas*_*lén 6

如何在 AsyncTask 完成后更新当前菜单以启用或禁用项目。

在我的用例中,我需要在 AsyncTask 加载数据时禁用我的菜单,然后在加载所有数据后,我需要再次启用所有菜单,以便让用户使用它。

这阻止了应用程序让用户在加载数据时点击菜单项。

首先,我声明一个状态变量,如果变量为 0 则显示菜单,如果该变量为 1 则隐藏菜单。

private mMenuState = 1; //I initialize it on 1 since I need all elements to be hidden when my activity starts loading.
Run Code Online (Sandbox Code Playgroud)

然后在我onCreateOptionsMenu()检查这个变量,如果它是 1 我禁用我的所有项目,如果不是,我只显示它们

 @Override
    public boolean onCreateOptionsMenu(Menu menu) {

        getMenuInflater().inflate(R.menu.menu_galeria_pictos, menu);

        if(mMenuState==1){
            for (int i = 0; i < menu.size(); i++) {
                menu.getItem(i).setVisible(false);
            }
        }else{
             for (int i = 0; i < menu.size(); i++) {
                menu.getItem(i).setVisible(true);
            }
        }

        return super.onCreateOptionsMenu(menu);
    }
Run Code Online (Sandbox Code Playgroud)

现在,当我的 Activity 开始时,onCreateOptionsMenu()将只调用一次,并且我的所有项目都将消失,因为我在开始时为它们设置了状态。

然后我创建了一个 AsyncTask ,在那里我将该状态变量设置为 0 onPostExecute()

这一步很重要!

当你打电话时invalidateOptionsMenu();它会重新启动onCreateOptionsMenu();

所以,在将我的状态设置为 0 后,我只是重绘了所有菜单,但这次我的变量为 0 ,也就是说,所有的菜单将在所有异步过程完成后显示,然后我的用户可以使用菜单.

 public class LoadMyGroups extends AsyncTask<Void, Void, Void> {

        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            mMenuState = 1; //you can set here the state of the menu too if you dont want to initialize it at global declaration. 

        }

        @Override
        protected Void doInBackground(Void... voids) {
           //Background work

            return null;
        }

        @Override
        protected void onPostExecute(Void aVoid) {
            super.onPostExecute(aVoid);

            mMenuState=0; //We change the state and relaunch onCreateOptionsMenu
            invalidateOptionsMenu(); //Relaunch onCreateOptionsMenu

        }
    }
Run Code Online (Sandbox Code Playgroud)

结果

在此处输入图片说明