(不建议使用)片段onOptionsItemSelected没有被调用


82

编辑: 这个问题是针对过时的夏洛克动作栏。现在应改为使用Android支持库

我添加了一个名为“分享给我”的操作栏菜单选项,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);
}

尝试同时以fragmentfragment 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()

Answers:


145

我也遇到了同样的问题:

片段中未调用onMenuItemSelected事件

搜索过的Google找不到解决方案,并且在FragmentActivity中添加onMenuItemSelected方法无法解决该问题。

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

注意:如果通过片段类的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);
    }   
}

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

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

在片段的onCreate方法中


12
对我来说,为了截取片段上的菜单,我必须在FragmentActivity的onOptionsItemSelected和片段的onOptionsItemSelected上返回“ false”,以执行所需的行为。
爱迪生·桑托斯

1
setHasOptionsMenu(true);的片段 在的onCreate和公共布尔onOptionsItemSelected(菜单项项){}方法做了魔法
莫伊塞斯

@Felixqk我在使用片段时遇到了这样的问题。我有两个片段。但是片段2的OnOptionsSelectedItem没有被调用。片段2显示片段1的菜单选项。
Roon13 2015年

@ Roon13删除super.onCreateOptionsMenu; 来自片段的onCreateOptionsMenu。+ setHasOptionsMenu(true); 为我工作,而没有删除Activity onOptionsItemSelected。
ahmadalibaloch'3

129

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

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

  2. onCreateOptionsMenu(Menu menu, MenuInflater inflater)在Fragment中重写(如果您想在Fragment的菜单中执行其他操作)和onOptionsItemSelected(MenuItem item)方法。

  3. 在Activity的onOptionsItemSelected(MenuItem item)方法内,请确保您false将在Fragment的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;
}

6
return false在Activity上onOptionItemSelected是关键。只需更换return super.onOptionItemSelected(item);
Youngjae 2014年

1
完美地工作。谢谢马可。
Rajeev Sahu 2014年

2
好答案。当它处于片段中时,应将onCreateOptionsMenu(菜单菜单)更改为onCreateOptionsMenu(菜单菜单,MenuInflater充气器)
克里斯·斯普拉格

1
这是很好的解决方案。Thnakx Marco HC
Darsh Patel 2014年

1
伟大的解决方案,我的朋友!谢谢!
Han Tran 2015年

5

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

活动

@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);” 活动中的片段和片段非常重要,因为就像您将在调试中遵循代码一样,您会看到菜单事件函数将首先在活动上被调用,并且如果该项与活动开关中的ID不匹配,情况下,目标行:“ super.onOptionsItemSelected(item);” 根据需要,将在片段上调用onOptionsItemSelected函数。(如果您有很多片段,请确保在其中也包含该行,因为调用层次结构可能会有些复杂)。


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

希望它能帮助某人。


2

编辑以供ActionBar Sherlock使用

我不得不用

public boolean onMenuItemSelected(int featureId, MenuItem item) {

在主要活动中捕获菜单项


同样的问题,也为我修复了。你能告诉我为什么onOptionItemSelected不起作用吗?
nadeem gc 2014年

原因是夏洛克动作栏未使用此方法
user1634451 2014年

更改onMenuItemSelected以调用onOptionItemSelected,以便您的代码在从ABS移至appcompatlib时可以正常工作
slott

1
@nadeemgc不起作用的原因是因为Android知道两种类型的菜单:选项菜单和上下文菜单。Actionbar Sherlock使用上下文菜单,而onContextItemSelected不是调用onOptionsItemSelected。在onMenuItemSelected简单的转发点击正确的方法,这就是为什么它似乎是更好的工作。
Amru E.

@AmruE。谢谢您,它将对将来有所帮助。
nadeem gc 2015年

2

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

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


0

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


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
         ...
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.