片段中的Android选项菜单

mis*_*man 378 android android-fragments android-optionsmenu

我试图从一组片段添加一个项目到选项菜单.

我创建了一个新MenuFragment类,并为我希望包含菜单项的片段扩展了这个.这是代码:

public class MenuFragment extends Fragment {

    MenuItem fav;

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

    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
        fav = menu.add("add");
        fav.setIcon(R.drawable.btn_star_big_off);
    }
}
Run Code Online (Sandbox Code Playgroud)

由于某种原因,onCreateOptionsMenu似乎没有运行.

Kuf*_*ffs 581

调用超级方法:

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

@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
    // TODO Add your menu entries here
    super.onCreateOptionsMenu(menu, inflater);
}
Run Code Online (Sandbox Code Playgroud)

将日志语句放在代码中以查看是否未调用该方法,或者您的代码是否未修改该菜单.

此外,还要确保您呼叫setHasOptionsMenu(boolean)onCreate(Bundle)通知,它应该参与选项菜单处理的片段.

  • 没有在Fragment的onCreate中调用setHasOptionsMenu(true)现在已经让我两次了 (175认同)
  • 请注意,Fragment.onCreateOptionsMenu(Menu,MenuInflater)是一个空方法,因此根本不需要调用super.这里唯一的错误是错误的方法签名,并且onCreate()中可能缺少setHasOptionsMenu() (14认同)
  • 我正在将我的Activity转移到Fragment并遇到了这个问题.方法签名已从public boolean更改为public void,并且参数也已更改.一定要注意这个! (6认同)
  • 将super.onCreateOptionsMenu替换为inflater.inflate(R.menu.menu_custom,menu); (5认同)
  • 感谢您的帮助,我添加了超级方法,并意识到我已经删除了@Override,所以添加了这个,eclipse抛出一个错误,所以我替换了MenuInflater来导入android.view.MenuInflater; 而不是导入android.support.v4.view.MenuInflater; 现在一切正常 (2认同)

Mar*_* HC 190

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

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

  2. onCreateOptionsMenu(Menu menu, MenuInflater inflater)在片段中覆盖(如果你想在Fragment的菜单中做一些不同的事情)和onOptionsItemSelected(MenuItem item)方法.

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

一个例子:

活动

@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;
}
Run Code Online (Sandbox Code Playgroud)

分段

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;
}
Run Code Online (Sandbox Code Playgroud)

  • 这必须是必须接受的答案.花了5个小时后帮帮我:) (13认同)
  • @Marco HC您的代码工作正常.但是,如果我想隐藏Activity或Fragment的某些菜单呢?您已经提到了在哪里实现哪个选项菜单(在活动和片段中).但是,如果我想隐藏一些菜单怎么办? (3认同)
  • 只是缺少`setHasOptionsMenu(true);`谢谢 (2认同)
  • 在某些设备上的 viewPager 上,菜单仅在您第二次转到片段时显示 (2认同)
  • 我经常来这里参考,最好的答案. (2认同)

Mat*_*ord 154

如果您发现onCreateOptionsMenu(Menu menu, MenuInflater inflater)未调用该方法,请确保从Fragment的onCreate(Bundle savedInstanceState)方法中调用以下内容:

setHasOptionsMenu(true)
Run Code Online (Sandbox Code Playgroud)

  • 好点子.我从静态newInstance方法调用setHasOptionMenu方法.因为我只是在savedInstanceState为null时附加我的片段,所以当屏幕配置改变时,将不会创建菜单.片段的onCreate方法是将setHasOptionMenu设置为true的正确位置. (2认同)

Ped*_*ito 53

就我而言,我需要一个菜单​​来刷新menu特定片段内部,因为我使用了:

片段:

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

@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {

    // TODO Add your menu entries here
    inflater.inflate(R.menu.menu, menu);
    super.onCreateOptionsMenu(menu, inflater);
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
    case R.id.exit:
        System.exit(1);
        break;

    case R.id.refresh:
        webView.reload();
        break;
    }
    return true;

}
Run Code Online (Sandbox Code Playgroud)

文件menu.xml

<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:id="@+id/exit" android:title="Exit" android:icon="@drawable/ic_action_cancel" />
    <item android:id="@+id/refresh" android:title="Refresh" android:icon="@drawable/ic_action_refresh" />
</menu>
Run Code Online (Sandbox Code Playgroud)


Par*_*sha 23

menu.xml你应该添加所有菜单项.然后,您可以隐藏在初始加载中不想看到的项目.

menu.xml文件

<item
    android:id="@+id/action_newItem"
    android:icon="@drawable/action_newItem"
    android:showAsAction="never"
    android:visible="false"
    android:title="@string/action_newItem"/>
Run Code Online (Sandbox Code Playgroud)

添加setHasOptionsMenu(true)onCreate()方法以调用Fragment类中的菜单项.

FragmentClass.java

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setHasOptionsMenu(true);
}
Run Code Online (Sandbox Code Playgroud)

您不需要onCreateOptionsMenu再次在Fragment类中重写.可以通过onPrepareOptionsMenuFragment中提供的覆盖方法更改(添加/删除)菜单项.

@Override
public void onPrepareOptionsMenu(Menu menu) {
    menu.findItem(R.id.action_newItem).setVisible(true);
    super.onPrepareOptionsMenu(menu);

}
Run Code Online (Sandbox Code Playgroud)


Ges*_*sit 21

有一种新的方法可以做到这一点,因为androidx.activity:activity:1.4.0

您应该使用MenuProvider API。

它的使用方法如下:

您不应该调用super.setHasOptionMenu并实现,而onCreateOptionsMenu应该addMenuProvider调用onViewCreated.

一个例子:

class ExampleFragment : Fragment(R.layout.fragment_example) {

  override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    // The usage of an interface lets you inject your own implementation
    val menuHost: MenuHost = requireActivity()
  
    // Add menu items without using the Fragment Menu APIs
    // Note how we can tie the MenuProvider to the viewLifecycleOwner
    // and an optional Lifecycle.State (here, RESUMED) to indicate when
    // the menu should be visible
    menuHost.addMenuProvider(object : MenuProvider {
      override fun onCreateMenu(menu: Menu, menuInflater: MenuInflater) {
        // Add menu items here
        menuInflater.inflate(R.menu.example_menu, menu)
      }

      override fun onMenuItemSelected(menuItem: MenuItem): Boolean {
        // Handle the menu selection
        return true
      }
    }, viewLifecycleOwner)
  }
Run Code Online (Sandbox Code Playgroud)

来源:活动变更日志


Mar*_*ius 19

TL; DR

使用android.support.v7.widget.Toolbar和只做:

toolbar.inflateMenu(R.menu.my_menu)
toolbar.setOnMenuItemClickListener {
    onOptionsItemSelected(it)
}
Run Code Online (Sandbox Code Playgroud)

独立工具栏

大多数建议的解决方案setHasOptionsMenu(true)仅在父Activity在其布局中具有工具栏并通过声明时才起作用setSupportActionBar().然后片段可以参与这个确切的ActionBar的菜单群:

Fragment.onCreateOptionsMenu():初始化Fragment主机的标准选项菜单的内容.

如果您想要一个特定片段的独立工具栏和菜单,您可以执行以下操作:

menu_custom_fragment.xml

<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
    <item
        android:id="@+id/menu_save"
        android:title="SAVE" />
</menu>
Run Code Online (Sandbox Code Playgroud)

custom_fragment.xml

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <android.support.v7.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

    ...
Run Code Online (Sandbox Code Playgroud)

CustomFragment.kt

override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
    val view = inflater.inflate(layout.custom_fragment, container, false)
    val toolbar = view.findViewById<Toolbar>(R.id.toolbar)
    toolbar.inflateMenu(R.menu.menu_custom_fragment)
    toolbar.setOnMenuItemClickListener {
        onOptionsItemSelected(it)
    }
    return view
}

override fun onOptionsItemSelected(item: MenuItem): Boolean {
    return when (item.itemId) {
        R.id.menu_save -> {
            // TODO: User clicked the save button
            true
        }
        else -> super.onOptionsItemSelected(item)
    }
}
Run Code Online (Sandbox Code Playgroud)

是的,就这么简单.你甚至不需要覆盖onCreate()onCreateOptionsMenu().

PS:这只是一起工作android.support.v4.app.Fragmentandroid.support.v7.widget.Toolbar(也一定要使用AppCompatActivityAppCompat主题在你的styles.xml).


Spl*_*nky 16

在充气菜单之前,您需要使用menu.clear().

@Override
    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
        menu.clear();
        inflater.inflate(R.menu.menu, menu);
        super.onCreateOptionsMenu(menu, inflater);
    }
Run Code Online (Sandbox Code Playgroud)

@Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setHasOptionsMenu(true);
    }
Run Code Online (Sandbox Code Playgroud)


小智 10

就我而言,这是步骤.

步骤1

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

    // Here notify the fragment that it should participate in options menu handling.
    setHasOptionsMenu(true);
}
Run Code Online (Sandbox Code Playgroud)

第2步

@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
    // First clear current all the menu items
    menu.clear();

    // Add the new menu items
    inflater.inflate(R.menu.post_stuff, menu);

    super.onCreateOptionsMenu(menu, inflater);
}
Run Code Online (Sandbox Code Playgroud)

步骤3

 @Override
public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
        case R.id.post_stuff:
            Log.d(TAG, "Will post the photo to server");
            return true;
        case R.id.cancel_post:
            Log.d(TAG, "Will cancel post the photo");
            return true;
        default:
            break;
    }
    return super.onOptionsItemSelected(item);
}
Run Code Online (Sandbox Code Playgroud)


小智 8

如果要添加菜单自定义

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

@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
    inflater.inflate(R.menu.menu_custom, menu);
}
Run Code Online (Sandbox Code Playgroud)


far*_*d_z 7

我遇到了同样的问题,我的片段是ViewPager的页面.它发生的原因是我在实例化FragmentPagerAdapter时使用子片段管理器而不是活动支持片段管理器.