(已弃用)片段onOptionsItemSelected未被调用

时间:2013-02-23 01:13:25

标签: android android-fragments android-actionbar

修改 这个问题是针对已弃用的sherlock操作栏。现在应该使用Android支持库

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

我正在添加它

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

9 个答案:

答案 0 :(得分:145)

同样的问题发生在我身上:

  

onMenuItemSelected事件未在Fragment中调用

搜索谷歌无法找到解决方案,并在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);
    }   
}

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方法中

答案 1 :(得分:126)

我遇到了同样的问题,但我认为最好总结一下并介绍最后一步让它运转起来:

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

  2. 在片段中覆盖onCreateOptionsMenu(Menu menu, MenuInflater inflater)(如果您想在片段菜单中执行不同的操作)和onOptionsItemSelected(MenuItem item)方法。

  3. 在您的活动的onOptionsItemSelected(MenuItem item)方法中,确保在Fragment的false方法中实施菜单项操作时返回onOptionsItemSelected(MenuItem item)

  4. 一个例子:

    活动

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

答案 2 :(得分:5)

我注意到人们给你的解决方案是在活动中实现你的menue项的代码而不是片段。 如果你已经在片段中实现了代码而不是活动'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);”在活动和片段中非常重要,因为好像你将遵循调试中的代码,你会看到将首先在Activity上调用menue事件函数,如果该项与activity的switch中的id不匹配 - 例如,degault行:“super.onOptionsItemSelected(item);”将按照我们的意愿调用片段上的onOptionsItemSelected函数。 (如果你有很多碎片,请确保在它们中也有这一行,因为调用hirarchy可能有些复杂)。

答案 3 :(得分:2)

编辑操作栏sherlock使用

我必须使用

public boolean onMenuItemSelected(int featureId, MenuItem item) {

在主要活动中捕获菜单项

答案 4 :(得分: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);
}

希望它有所帮助。

答案 5 :(得分:2)

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

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

答案 6 :(得分:0)

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

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

确保使用正确的!

答案 7 :(得分:0)

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

答案 8 :(得分: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
         ...