51

我的最后一个问题得到了非常有用的提示,我希望这次不会有所不同:) 首先,让我解释一下情况。我有一个包含 2 个片段的活动。对于每个片段,我都有一个 xml 菜单布局,第一个有四个菜单条目,第二个只有一个。现在首先加载具有四个菜单项的片段。在我设置的 onCreate 方法中

this.setHasOptionsMenu(true);

onCreateOptionsMenu 方法

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

xml 文件如下所示:

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="@+id/menu_refresh"
      android:icon="@drawable/ic_action_search"
      android:title="Refresh"
      android:visible="true"
      android:showAsAction="ifRoom|withText" />
<item android:id="@+id/menu_clearall"
      android:icon="@drawable/ic_action_search"
      android:title="Clear"
      android:visible="true"
      android:showAsAction="ifRoom|withText" />
<item android:id="@+id/menu_addcontent"
      android:icon="@drawable/ic_action_search"
      android:title="Add Content"
      android:visible="true"
      android:showAsAction="ifRoom|withText" />
<item android:id="@+id/menu_newlist"
      android:icon="@drawable/ic_action_search"
      android:title="New List"
      android:visible="true"
      android:showAsAction="ifRoom|withText" />    
</menu>

这工作正常。所有菜单项都在那里,我可以单击它们并做出响应。现在,当我单击“添加内容”菜单时,会加载另一个片段。我也设置了

this.setHasOptionsMenu(true);

onCreateOptionsMenu 方法

@Override 
public void onCreateOptionsMenu (Menu menu, MenuInflater inflater) {
    Log.i("FragCreateList","onCreateOptionsMenu called");
    super.onCreateOptionsMenu(menu, inflater);
    inflater.inflate(R.menu.menu_fragcreatelist, menu);
}

xml文件

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="@+id/menu_editdone"
      android:icon="@drawable/ic_action_search"
      android:title="Edit Done"
      android:visible="true"
      android:showAsAction="ifRoom|withText" />         
</menu>

但在新片段中,我看不到任何菜单项。既不是在操作栏中,也不是当我按下硬件菜单按钮时。在前一个片段中,两个菜单项在操作栏中,其余两个在按下硬件按钮时出现。但是这里什么都没有显示。我收到调用 onCreateOptionsMenu 方法的 logcat 消息,但没有任何反应。(我什至接到了对我的(空)onPrepareOptionsMenu 方法的调用,该方法应该在菜单显示之前调用,仍然没有)任何线索可能是错误的?调用 invalidateOptionsMenu 没有任何作用。此外,我不知道该调用哪一个,因为有一个 getActivity().invalidateOptionsMenu 和一个 getFragmentManager().invalidateOptionsMenu... 在此先感谢。

编辑 :

<uses-sdk
    android:minSdkVersion="14"
    android:targetSdkVersion="15" />
4

15 回答 15

94

我在 onCreateView 中添加了setHasOptionsMenu(true)并且效果很好

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {
    setHasOptionsMenu(true);
    return inflater.inflate(R.layout.my_example_fragment, container, false);

}
于 2013-12-02T10:50:01.003 回答
55

在膨胀菜单之前使用 menu.clear()。

@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
    super.onCreateOptionsMenu(menu, inflater);
    menu.clear();
    inflater.inflate(R.menu.mnulayout, menu);
}
于 2012-09-20T20:40:38.553 回答
14

首先你的片段必须在onCreate

    setHasOptionsMenu(true);

然后您必须检查您的活动是否具有类似 NoActionBar 的主题,这有点棘手,但如果您的活动具有该主题,则无论您在哪里调用setHasOptionsMenu(true)片段都不会画她

于 2017-10-10T02:03:43.740 回答
8

我有同样的问题。我通过在应用于 myApp 上下文的项目中使用 showAsAction 来修复它:

<menu xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:myapp="http://schemas.android.com/apk/res-auto">
    <item android:id="@+id/action_refresh"
          android:icon="@drawable/ic_refresh"
          android:title="refresh"
          android:visible="true"
          myapp:showAsAction="ifRoom|withText"/>
</menu>

对不起,对你来说太晚了,但它可能对其他人有用。

于 2013-10-14T13:40:58.053 回答
7

这实际上对我有用,也可能是您的解决方案。

@Override
public void onActivityCreated(Bundle savedInstanceState) {
    // TODO Auto-generated method stub
    super.onActivityCreated(savedInstanceState);
    setHasOptionsMenu(true);
}
于 2015-10-05T12:13:28.903 回答
6

发生这种情况是因为您的设备有硬件菜单按钮。因此,变量“sHasPermanentMenuKey”的值在 ViewConfiguration hasPermanentMenuKey()中为真。您必须使用反射将此变量的值设置为 false。例子:

// this method force showing menu button in device with hardware menu button
private void showOverflowMenu(FragmentActivity activity) {
    try {
        ViewConfiguration config = ViewConfiguration.get(activity);
        Field menuKeyField = ViewConfiguration.class.getDeclaredField("sHasPermanentMenuKey");
        if (menuKeyField != null) {
            menuKeyField.setAccessible(true);
            menuKeyField.setBoolean(config, false);
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
}

注意:在活动的 onCreate() 中使用此方法,而不是在片段的方法 onCreate() 中使用。

于 2014-10-15T08:13:17.830 回答
4

setSupportActionBar(youtoolbar)如果您Toolbar在活动中使用 a ,请确保设置。

于 2019-08-17T04:38:35.603 回答
3

在片段中注册选项/上下文菜单时,您通常需要等到 onActivityCreated() 调用以确保有一个活动可以将菜单绑定到。尝试此处建议的修复程序,看看是否有帮助:

ListFragment 的上下文菜单

于 2012-08-23T12:13:23.393 回答
2

对于片段类,为了让您查看菜单,请在 onCreateView() 方法或 onCreateAcivity() 方法中添加 sethasoptionsmenu(true)。但是我将我的添加到 onCreateView() 方法中。希望它可以帮助某人

于 2017-06-17T14:45:50.530 回答
1

选项菜单可能被隐藏,但可以工作。您可以通过长按硬件按钮“最近的应用程序”来检查这一点。

除了上面提到的隐藏菜单的原因外,还有可能是AndroidManifest.xml中没有指定action bar的主题

    <application
        ...
        android:theme="@style/Theme.Design.NoActionBar"
        ...
    </application>
于 2019-12-02T08:02:27.807 回答
0

尝试在片段中将 onCreateOptionsMenu 更改为 onPrepareOptionsMenu,我遇到了同样的问题,据我所知,这为我解决了...

于 2012-08-23T11:27:27.467 回答
0

如果所有解决方案都不起作用,请尝试以下操作:

onCreateView()在方法中添加以下行

setHasOptionsMenu(true)

还在onViewCreated()方法中添加以下行

(activity as AppCompatActivity?)!!.setSupportActionBar(customToolbar as Toolbar?)

其中customToolBar是xml文件中添加的工具栏的id

于 2022-01-19T08:02:26.857 回答
0

您的活动需要扩展ActionBarActivity。您可能有一个只扩展 Activity。强文本

于 2015-10-04T21:52:05.183 回答
0

此代码解释了显示 Fragment OnOptionItem 选择项的解决方案。和选项菜单中项目的 OnClicklistner

如果应用程序为每个单独的片段使用自定义工具栏。

片段测试.java

public class FragmentTest extends BaseFragmentHelper {
    public static final String TAG = FragmentRegistration.class.getSimpleName();
    View testFragmetnView;
   
    Toolbar toolbarRegistration;

    @Override
    public void onAttachFragment(@NonNull Fragment childFragment) {
        super.onAttachFragment(childFragment);
    }

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

    }

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        testFragmetnView= inflater.inflate(R.layout.test_layout, container, false);
        //Intialize Toolbar
        toolbarRegistration=(Toolbar) registrationFragmentView.findViewById(R.id.toolbarRegistration_id);
        //inflate Menu layout
        toolbarRegistration.inflateMenu(R.menu.menu_test);
        //onOption Menu OnClicklistner
        toolbarRegistration.setOnMenuItemClickListener(new Toolbar.OnMenuItemClickListener() {
        @Override
        public boolean onMenuItemClick(MenuItem item) {
           switch (item.getItemId()){
                case R.id.test1:{
                    Toast.makeText(getActivity(),"Test 1",Toast.LENGTH_SHORT).show();
                    break;
                }
                case R.id.test2:{
                    Toast.makeText(getActivity(),"Test 2",Toast.LENGTH_SHORT).show();
                    break;
                }
            }
            return false;
        }
    });
        return testFragmetnView;
    }

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

    @Override
    public void onStart() {
        super.onStart();
    }

    @Override
    public void onResume() {
        super.onResume();

    }

    @Override
    public void onDetach() {
        super.onDetach();
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
    }

    @Override
    public void onDestroyView() {
        super.onDestroyView();
    }

    @Override
    public String toString() {
        return FragmentTest.class.getSimpleName();
    }
  }

test_layout.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:app="http://schemas.android.com/apk/res-auto">
    <androidx.appcompat.widget.Toolbar
        android:id="@+id/toolbarRegistration_id"
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"
        app:contentInsetLeft="0dp"
        android:background="@color/purple_700"
        app:contentInsetStart="0dp">
        <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent">
            <ImageView
                android:id="@+id/imageView_toolbar_cancel_id"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:src="@drawable/cancel_icon"
                android:layout_centerVertical="true"
                android:layout_marginLeft="5dp">
            </ImageView>
            <TextView
                android:id="@+id/toolbar_textViewheader_id"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_centerVertical="true"
                android:layout_marginLeft="50dp"
                android:textColor="@color/white"
                android:textStyle="bold"
                android:text="Registration"
                android:textSize="20dp">
            </TextView>
        </RelativeLayout>
    </androidx.appcompat.widget.Toolbar>
</RelativeLayout>

菜单测试

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">
    <item
        android:id="@+id/test1"
        android:title="Test 1"
        android:visible="true" />
    <item
        android:id="@+id/test2"
        android:title="Test 2"
        android:visible="true"
        />
</menu>
于 2021-05-03T09:49:03.163 回答
-1

由于上述建议都没有解决我的问题,因此添加得很晚。我的设备(2.3.5)的选项菜单有一个非常糟糕的时间问题,我不得不走一条不同的路线,并使用活动中的充气机在 onprepare 部分创建菜单:

@Override
public void onPrepareOptionsMenu(Menu menu)
{
    if (Build.VERSION.SDK_INT < 11) {
        menu.clear();
        getActivity().getMenuInflater().inflate(R.menu.message_thread, menu);
    }
于 2014-10-23T19:21:57.067 回答