82

编辑: 这个问题是针对已弃用的夏洛克动作栏的。现在应该改用 Android 支持库

我为我添加了一个名为 share 的操作栏菜单选项fragment,但未捕获到选择事件

我像这样添加它

@Override
public void onCreateOptionsMenu (Menu menu, MenuInflater inflater) {
    MenuItem item = menu.add(0, 7,0, R.string.share);
    item.setIcon(R.drawable.social_share).setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
}

试图在两者中fragment捕捉fragment activity

@Override
public boolean onOptionsItemSelected(MenuItem item) {

    switch (item.getItemId()) {
        case 7:
            Intent share = new Intent(Intent.ACTION_SEND);
            share.setType("text/plain");
            share.putExtra(Intent.EXTRA_TEXT, "I'm being sent!!");
            startActivity(Intent.createChooser(share, "Share Text"));
            return true;
        default:
            return super.onOptionsItemSelected(item);
    }
}

setHasOptionsMenu(true);onCreate().

4

9 回答 9

146

我也遇到了同样的问题:

片段中未调用 onMenuItemSelected 事件

搜google找不到解决办法,在FragmentActivity中添加onMenuItemSelected方法也没有解决。

最后通过参考http://developer.android.com/guide/topics/ui/actionbar.html解决它

注意:如果您通过 Fragment 类的 onCreateOptionsMenu 回调从片段中添加菜单项,那么当用户选择片段的其中一项时,系统会为该片段调用相应的 onOptionsItemSelected() 方法。然而,活动有机会首先处理事件,因此系统在为片段调用相同的回调之前对活动调用 onOptionsItemSelected()。

这意味着只有当您在活动的 onOptionsItemSelected() 中没有该菜单项处理程序时,才会调用片段上的 onOptionsItemSelected()。

代码如下-----在 FragmentActivity 上删除R.action.add的处理程序):

@Override
public boolean onOptionsItemSelected(MenuItem item) {

    switch (item.getItemId()) {
        case android.R.id.home:
            popBackStack();             
            return true;        
        case R.id.action_search:
            searchAction();
            return true;
        case R.id.action_logout:
            userLogout();
            return true;
        //case R.id.action_add:
            //return true;    
        default:
            return super.onOptionsItemSelected(item);
    }   
}

R.action.add在 Fragment 上的处理程序如下所示:

@Override
public boolean onOptionsItemSelected(MenuItem item) {

    Log.d("onOptionsItemSelected","yes");
    switch (item.getItemId()) {
        case R.id.action_add:
            add();
            return true;    
        default:
            return super.onOptionsItemSelected(item);
    }
}

最后记得添加

    setHasOptionsMenu(true);

在 Fragment 的 onCreate 方法中

于 2013-05-27T07:46:21.310 回答
131

我遇到了同样的问题,但我认为最好总结并介绍最后一步以使其正常工作:

  1. setHasOptionsMenu(true)在 Fragment 的方法中添加onCreate(Bundle savedInstanceState)方法。

  2. 覆盖onCreateOptionsMenu(Menu menu, MenuInflater inflater)(如果您想在 Fragment 的菜单中做一些不同的事情)和 FragmentonOptionsItemSelected(MenuItem item)中的方法。

  3. 在 Activity 的onOptionsItemSelected(MenuItem item)方法中,确保在 Fragment 的方法false中实现菜单项操作时返回。onOptionsItemSelected(MenuItem item)

一个例子:

活动

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    MenuInflater inflater = getSupportMenuInflater();
    inflater.inflate(R.menu.main, menu);
    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
    case R.id.activity_menu_item:
        // Do Activity menu item stuff here
        return true;
    case R.id.fragment_menu_item:
        // Not implemented here
        return false;
    default:
        break;
    }

    return false;
}

分段

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setHasOptionsMenu(true);
    ....
}

@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
    // Do something that differs the Activity's menu here
    super.onCreateOptionsMenu(menu, inflater);
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
    case R.id.activity_menu_item:
        // Not implemented here
        return false;
    case R.id.fragment_menu_item:
        // Do Fragment menu item stuff here
        return true;
    default:
        break;
    }

    return false;
}
于 2013-08-19T17:00:41.480 回答
6

我注意到人们给你的解决方案是在活动中为你的菜单项而不是片段实现代码。我认为如果您在片段中实现代码而不是活动,它看起来会更加组织化,因为在我看来它看起来更好。为此,请执行以下操作:

活动

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

 @Override
    public boolean onOptionsItemSelected(MenuItem item)
    {            
        switch (item.getItemId())
        {
            case R.id.SomeIDInTheMenueOfTheActivity:
            {
               //something();
                break;
            }
            default:
             //do something default and add the code under : 
             return super.onOptionsItemSelected(item);
        }
        return true;
    }

分段

 @Override
    public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);  
            setHasOptionsMenu(true);      
        }

  @Override
    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater)
    {           
        super.onCreateOptionsMenu(menu, inflater);
    }

     @Override
        public boolean onOptionsItemSelected(MenuItem item)
        {
            switch (item.getItemId())
            {           
                case R.id.SomeIDInFragmentMenue:
                {             
                    break;
                }

                default:
                    return super.onOptionsItemSelected(item);
            }

            return true;
        }

现在的行(和喜欢):“return super.onOptionsItemSelected(item);” 在activity和fragment中是非常重要的,因为就像你在debug中跟着代码一样,你会看到首先在Activity上调用menue events函数,如果item与activity的switch中的id不匹配——情况下,默认行:“super.onOptionsItemSelected(item);” 如我们所愿,将在片段上调用 ​​onOptionsItemSelected 函数。(如果您有很多片段,请确保其中也包含该行,因为调用层次结构可能有些复杂)。

于 2016-06-10T16:39:32.603 回答
2

我正在使用actionbarsherlock。这对我有用:

1) 创建 dummy_menu.xml 菜单

<?xml version="1.0" encoding="utf-8"?>

<menu xmlns:android="http://schemas.android.com/apk/res/android" android:layout_height="match_parent" android:layout_width="fill_parent" >
<item
      android:title=""
      android:showAsAction="never"
      android:id="@+id/dummyMenu"
        />

2)在活动中像这样膨胀菜单:

@Override
public boolean onCreateOptionsMenu(com.actionbarsherlock.view.Menu menu) {
    com.actionbarsherlock.view.MenuInflater inflater = getSupportMenuInflater();
   inflater.inflate(R.menu.dummy_menu,menu);
   return super.onCreateOptionsMenu(menu);
}

3)在片段 onCreateView 调用 setHasOptionsMenu(true) 并覆盖 onCreateOptionsMenu 和 onOptionsItemSelected 也像这样隐藏 dummyMenu(在片段中)

    @Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
    inflater.inflate(R.menu.fragment_actions, menu);
    MenuItem item = menu.findItem(R.id.dummyMenu);
    item.setVisible(false);
    super.onCreateOptionsMenu(menu, inflater);
}

希望它可以帮助某人。

于 2014-06-03T17:31:09.453 回答
2

非常简单,您可以在片段中执行此操作,以确保您的操作正确收听:

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setHasOptionsMenu(true);
}
于 2015-03-18T10:41:26.503 回答
2

编辑操作栏 sherlock 使用

我不得不使用

public boolean onMenuItemSelected(int featureId, MenuItem item) {

在主要活动中捕获菜单项

于 2013-02-25T18:14:37.193 回答
0

我有这个问题。这是因为我覆盖了错误的方法

onOptionsItemSelected(com.actionbarsherlock.view.MenuItem item) 是我使用的。

确保您使用的是正确的!

于 2014-06-19T06:59:40.407 回答
0

您必须toolbar.bringToFront();在活动中添加此代码下一组工具栏

 public class MainActivity extends AppCompatActivity {
     protected void onCreate(Bundle savedInstanceState) {
        ...

        Toolbar toolbar = findViewById(R.id.toolbar);
        toolbar.setTitle("Yazd");
        setSupportActionBar(toolbar);
        toolbar.bringToFront(); // <<= add here
         ...
于 2019-05-29T14:49:36.877 回答
0

您没有链接到活动方法中的超类。请让 onCreateOptionsMenu() 返回 super.onCreateOptionsMenu(menu),让 onOptionsItemSelected() 返回 super.onOptionsItemSelected(item) (您正在处理的项目除外,它应该返回 true 表示您已处理该事件)

于 2017-03-11T10:18:32.143 回答