片段中的菜单未显示

时间:2012-08-23 11:15:42

标签: android android-fragments android-menu

我对上一期的问题提供了非常有用的提示,我希望这次不会有所不同:)首先,让我解释一下情况。我有一个有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" />

14 个答案:

答案 0 :(得分:87)

我在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);

}

答案 1 :(得分:52)

在充气菜单之前使用menu.clear()。

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

答案 2 :(得分:7)

我遇到了同样的问题。我使用应用于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>

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

答案 3 :(得分:6)

首先,您的片段必须包含在onCreate

    setHasOptionsMenu(true);

然后你必须检查你的活动DONT是否具有类似NoActionBar的主题 它有点棘手,但如果你的活动有这个主题并不重要,你称之为setHasOptionsMenu(true)的片段不会给她画画

答案 4 :(得分:5)

这是因为您的设备有硬件菜单按钮。因此变量的价值&#34; sHasPermanentMenuKey&#34;在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()方法。

答案 5 :(得分:5)

这实际上适合我,也可能是你的解决方案。

@Override
public void onActivityCreated(Bundle savedInstanceState) {
    // TODO Auto-generated method stub
    super.onActivityCreated(savedInstanceState);
    setHasOptionsMenu(true);
}

答案 6 :(得分:3)

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

Context menu from a ListFragment

答案 7 :(得分:2)

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

答案 8 :(得分:0)

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

答案 9 :(得分:0)

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

答案 10 :(得分:0)

对于片段类,您可以看到添加的菜单 setCreateView()方法或onCreateAcivity()方法中的sethasoptionsmenu(true)。 但我将我的内容添加到onCreateView()方法中。希望它可以帮助某人

答案 11 :(得分:0)

选项菜单可能被隐藏,但是可以使用。您可以通过长按硬件按钮“最近的应用程序”来进行检查。

除了上述提到的隐藏菜单的原因外,AndroidManifest.xml中可能还没有指定操作栏的主题

    <application
        ...
        android:theme="@style/Theme.Design.NoActionBar"
        ...
    </application>

答案 12 :(得分:0)

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

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

FragmentTest.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>

menu_test

<?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>

答案 13 :(得分:-1)

由于上述建议均未解决我的问题,因此很晚才添加。我的设备(2.3.5)在选项菜单上有一个不好的计时问题,我不得不走另一条路线,并使用活动中的inflater在onprepare部分创建菜单:

@Override
public void onPrepareOptionsMenu(Menu menu)
{
    if (Build.VERSION.SDK_INT < 11) {
        menu.clear();
        getActivity().getMenuInflater().inflate(R.menu.message_thread, menu);
    }