如何以编程方式触发/点击Android中的菜单项?

44

我在 menu_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:id="@+id/action_restart" android:title="Restart"
        android:orderInCategory="1" />
    <item android:id="@+id/action_clear" android:title="Clear"
        android:orderInCategory="2" />
    <item android:id="@+id/action_update" android:title="Update"
        android:orderInCategory="3" />
    <item android:id="@+id/action_about" android:title="About"
        android:orderInCategory="4" />
    <item android:id="@+id/action_try_restart" android:title="Try Restart"
        android:orderInCategory="5" />
</menu>

我在我的 onOptionsItemSelected 方法中有这个:

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    // Handle action bar item clicks here. The action bar will
    // automatically handle clicks on the Home/Up button, so long
    // as you specify a parent activity in AndroidManifest.xml.
    int id = item.getItemId();

    if (id == R.id.action_restart) {
        Toast.makeText(MainActivity.this, "Restart...", Toast.LENGTH_LONG).show();
    }

    if (id == R.id.action_clear) {
        Toast.makeText(MainActivity.this, "Clear...", Toast.LENGTH_LONG).show();
    }

    if (id == R.id.action_update) {
        Toast.makeText(MainActivity.this, "Update...", Toast.LENGTH_LONG).show();
    }

    if (id == R.id.action_about) {
        Toast.makeText(MainActivity.this, "About...", Toast.LENGTH_LONG).show();
    }

    if(id == R.id.action_try_restart) {
        // how to click / trigger the "action_restart" from here?
    }

    return super.onOptionsItemSelected(item);
}

我已尝试过:

MenuItem actionRestart = (MenuItem) findViewById(R.id.action_restart);
actionRestart; //

但是actionRestart引用并没有像clicktrigger等一样的功能。

我还想指出,我是Android开发的新手,来自PHP / JavaScript背景,所以这种Java面向对象编程对我来说都是全新的。

9个回答

56

使用performIdentifierAction方法,如下:

menu.performIdentifierAction(R.id.action_restart, 0);

我怎样能够从Activity的onCreate()方法中获取菜单(menu)? - alexanderktx
2
@p2lem8dev,你可以在public boolean onCreateOptionsMenu(Menu menu)中获取菜单。 - Simon
我需要的只是翻译文本。 - Dimitri Schultheis
这对我实际有效,谢谢。 - SoufianeKre
太好了! :) 这也适用于 NavigationView 菜单和菜单项。谢谢! - Victor

17

您应该手动调用您的监听器,并将所需的项目作为参数传递。

MenuItem actionRestart = (MenuItem) findViewById(R.id.action_restart);
onOptionsItemSelected(actionRestart);

2
我也会尝试这个!我已经按照Veselin Romic在上面的回答中所描述的方法创建了一个单独的方法。谢谢你。 - Zlatan Omerović
5
Java.lang.ClassCastException: android.support.v7.view.menu.ActionMenuItemView 无法转换为 android.view.MenuItem。 - Pablo Cegarra
在我的情况下,在 [onCreate] 方法中尝试查找视图时,它会抛出异常。我该怎么办才能到达那里? - alexanderktx
在onCreate()方法中,findViewById()方法返回null。代码应该放在哪里? - eastwater

10

我也想在这里分享我的解决方案。与其试图以编程方式单击菜单项,我创建了一个专门用于菜单项点击的方法,并在需要单击菜单项的任何地方调用它。 OnOptionsItemSelected 方法如下所示。您可以看到我将点击逻辑移动到了一个单独的方法中。

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    if (item.getItemId() == android.R.id.home) {
        homeClicked();
    }
    return super.onOptionsItemSelected(item);
}
private void homeClicked(){
    ...
}
现在你可以随时调用 homeClicked 来以编程方式单击菜单项。

1
好的方法,因为我们没有本地方法。 - MilapTank

10
据我所知,SDK中没有机制可以让您这样做。 这绝对不是标准做法。
我建议尽可能将逻辑与实际UI解耦,这样你就不需要模拟点击来触发操作了。由于您是Web开发人员,这应该很容易做到。
在这种情况下,您需要将吐司(Toast)重构为单独的方法(或多个方法),然后在单击菜单项以及手动触发时调用该方法。
或者,您可以尝试通过findViewById()返回的MenuItem将其传递给处理程序。但我不知道那是否有效。

1
你可以使用 performIdentifierAction 方法。 - Simon
请看@VadymVL的回答,这是完全可能的。 - Umar Ata

6

虽然这不是最好的方法,

MenuItem item_your_choice;

 @Override
public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.your_menu, menu);
    item_your_choice = menu.findItem(R.id.item_your_choice);
    return super.onCreateOptionsMenu(menu);
}

 @Override
public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
        case item_your_choice:
           //do whatever you want
            break;
        }
   return super.onOptionsItemSelected(item);
}

只需从任何方法中调用

onOptionsItemSelected(item_you_choice);

4
  1. Make global Menu

    public Menu mMenu;
    
  2. Assign menu to mMenu while override onCreateOptionMenu

    @Override
    public boolean onCreateOptionsMenu(Menu menu)
    {
        this.mMenu = menu;
        return super.onCreateOptionsMenu(menu);
    }
    
  3. Call event like this:

    if(mMenu != null) {
        MenuItem action = mMenu.findItem(R.id.action_restart);
    
        if(action != null) {
            onOptionsItemSelected(action);
        }
    }
    

2
根据您上面菜单项的示例:
<item android:id="@+id/action_restart" android:title="Restart"
        android:orderInCategory="1" />

使用callOnClick()方法:

((ActionMenuItemView)findViewById(R.id.action_restart)).callOnClick();

2

我不确定这是否是最好的方法,但以下是我的做法。

BottomNavigationItemView具有 callOnClick() 方法。

BottomNavigationItemView menuItem = findViewById(R.id.navigation_take_post);
menuItem.callOnClick();

-3

有一种标准方法可以实现这个 -
创建一个MenuItem类的新实例,并更改重写的方法getItemId(),使其返回所需菜单项的ID,其余部分保持不变。

MenuItem actionRestart = new MenuItem() {
                                             @Override
                                             public int getItemId() {
                                               return R.id.action_restart;
                                             }

                                             ...

                                           };
onOptionsItemSelected(actionRestart);

1
这将覆盖所有MenuItem的接口方法,使您的代码混乱。 - emen

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接