【问题标题】:Menu in Fragments not showing片段中的菜单未显示
【发布时间】:2012-08-18 21:25:16
【问题描述】:

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

【问题讨论】:

  • 从答案看来,这似乎是由很多事情引起的。我遇到了这个问题,因为我使用的是 FragmentActivity 而不是 AppCompatActivity,而且我一更改它就可以工作

标签: android android-fragments android-menu


【解决方案1】:

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

}

【讨论】:

  • 这对我也有用,谢谢!。我看了半打教程,包括官方的 android 文档,但没有提到这一点。可悲的是,在我学习 Android 开发的过程中,这种严重的遗漏已成为常规而不是例外......
【解决方案2】:

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

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

【讨论】:

  • +1,如果您有一个在多个片段之间切换的主要活动,并且您正在尝试使用自定义 &lt;menu&gt; 作为其中一个片段的操作栏,这就是您的解决方案想要。
【解决方案3】:

首先你的片段必须有onCreate

    setHasOptionsMenu(true);

然后您必须检查您的活动是否具有类似 NoActionBar 的主题 这有点棘手,但如果你的活动有那个主题,那么你在哪里调用setHasOptionsMenu(true) 并不重要,你的片段不会画她

【讨论】:

    【解决方案4】:

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

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

    【讨论】:

    • 注意:使用支持Fragment时使用android:showAsAction似乎没有任何效果,因此使用res-auto设置第二个命名空间至关重要。感谢您的帮助。
    • +1 @aglor 为这个金块,设置了所有其他东西,并且使用了 Eric 提到的 Support V4,不知道如何解决这个问题,谢谢。
    【解决方案5】:

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

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

    【讨论】:

      【解决方案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() 中使用。

      【讨论】:

        【解决方案7】:

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

        【讨论】:

          【解决方案8】:

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

          Context menu from a ListFragment

          【讨论】:

          • 嘿 jsmith,这是关于上下文菜单的,我分别说的是操作栏菜单项或硬件按钮菜单项。
          • 是的,我明白了。在阅读问题时,似乎暗示您在片段 onCreate 中调用了 setHasOptionsMenu(true)。我建议您将其移至两个片段的 onActivityCreated() 方法。这适用于选项菜单和上下文菜单。
          【解决方案9】:

          为了让你看到你的菜单添加一个片段类 在 onCreateView() 方法或 onCreateAcivity() 方法中设置 sethasoptionsmenu(true)。 但我将我的添加到 onCreateView() 方法中。希望它可以帮助某人

          【讨论】:

            【解决方案10】:

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

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

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

            【讨论】:

              【解决方案11】:

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

              【讨论】:

              • 将其更改为 @Override public void onPrepareOptionsMenu(Menu menu) { Log.i("FragCreateList","onPrepareOptionsMenu called"); MenuInflater inflater=new MenuInflater(getActivity()); inflater.inflate(R.menu.menu_fragcreatelist, 菜单); } 但仍然什么都没有……什么都没有显示。
              • 奇怪,我有两个片段的活动,经典模式,活动本身有一个菜单,每个片段都有自己的菜单。我在活动中有 onCreateOptionsMenu,在片段中有 onPrepareOptionsMenu。而且我将所有三个菜单组合在一起显示...
              • 也许我们误解了,我不希望我所有的菜单组合在一起,我希望这两个单独的菜单显示在两个单独的片段中,但只有一个片段显示一个菜单。我第一次在我的 Activity 中也有 onCreateOptions,但我认为它更有意义,所以将所有内容都移到了片段中。我刚刚用不同的设计方法解决了我的问题,但我仍然想知道为什么它不起作用:) 感谢您的努力。
              • @EI Duderino 和你一样的问题,你是怎么解决的?
              【解决方案12】:

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

              【讨论】:

                【解决方案13】:

                此代码解释了显示 Fragment OnOptionItem 选择项的解决方案。 和选项菜单中Items的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>
                

                【讨论】:

                  【解决方案14】:

                  如果没有一个解决方案有效,请尝试以下操作:

                  onCreateView() 方法中添加以下行

                  setHasOptionsMenu(true)
                  

                  onViewCreated()方法中也加入下面一行

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

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

                  【讨论】:

                    【解决方案15】:

                    由于上述建议都没有解决我的问题,因此添加得很晚。我的设备 (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);
                        }
                    

                    【讨论】:

                      猜你喜欢
                      • 1970-01-01
                      • 1970-01-01
                      • 1970-01-01
                      • 1970-01-01
                      • 1970-01-01
                      • 1970-01-01
                      • 2017-06-01
                      • 1970-01-01
                      • 1970-01-01
                      相关资源
                      最近更新 更多