首页 文章

片段中的Android选项菜单

提问于
浏览
348

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

我创建了一个新的 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);
    }
}

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

19 回答

  • 0

    我的问题略有不同 . 我做的一切都很对 . 但是我继承了托管片段的活动的错误类 .

    因此,要清楚,如果要覆盖片段中的 onCreateOptionsMenu(Menu menu, MenuInflater inflater) ,请确保承载此片段的活动类继承 android.support.v7.app.ActionBarActivity (如果您希望支持以下API级别11) .

    我继承了 android.support.v4.app.FragmentActivity 以支持低于11的API级别 .

  • 22

    调用超级方法:

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

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

    还要确保在 onCreate 中调用 SetHasOptionsMenu 来通知片段它应该参与选项菜单处理 .

  • 537

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

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

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

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

    一个例子:

    Activity

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

    Fragment

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

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

    setHasOptionsMenu(true)
    
  • 175

    就我而言,我需要一个菜单来刷新特定片段中的 webview ,因为我使用了:

    Fragment

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

    文件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>
    
  • 15

    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"/>
    

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

    FragmentClass.java

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

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

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

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

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

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

    就我而言,这是步骤 .

    步骤-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);
    }
    

    步骤-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);
    }
    

    步骤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);
    }
    
  • 1

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

  • 3

    如果要添加菜单自定义

    @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);
    }
    
  • 1

    菜单文件:

    <?xml version="1.0" encoding="utf-8"?>
    <menu xmlns:android="http://schemas.android.com/apk/res/android">
        <item
            android:id="@+id/play"
            android:titleCondensed="Speak"
            android:showAsAction="always"
            android:title="Speak"
            android:icon="@drawable/ic_play">
        </item>
        <item
            android:id="@+id/pause"
            android:titleCondensed="Stop"
            android:title="Stop"
            android:showAsAction="always"
            android:icon="@drawable/ic_pause">
        </item>
    </menu>
    

    活动代码:

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.speak_menu_history, menu);
        return true;
    }
    
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
    
            case R.id.play:
                Toast.makeText(getApplicationContext(), "speaking....", Toast.LENGTH_LONG).show();
                return false;
    
            case R.id.pause:
                Toast.makeText(getApplicationContext(), "stopping....", Toast.LENGTH_LONG).show();
                return false;
    
            default:
                break;
        }
    
        return false;
    }
    

    片段代码:

    @Override
    
    public void onCreate(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onCreate(savedInstanceState);
        setHasOptionsMenu(true);
    }
    
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
    
            case R.id.play:
                text = page.getText().toString();
                speakOut(text);
    
                // Do Activity menu item stuff here
                return true;
    
            case R.id.pause:
                speakOf();
    
                // Not implemented here
                return true;
    
            default:
                break;
        }
        return false;
    }
    
  • 2

    TL; DR

    使用 android.support.v7.widget.Toolbar 并执行:

    toolbar.inflateMenu(R.menu.my_menu)
    toolbar.setOnMenuItemClickListener {
        onOptionsItemSelected(it)
    }
    

    独立工具栏

    大多数建议的解决方案,例如 setHasOptionsMenu(true) 仅在 parent Activity has the Toolbar in its layout 时起作用,并通过 setSupportActionBar() 声明它 . 然后片段可以参与这个确切的ActionBar的菜单群:

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

    If you want a standalone toolbar and menu for one specific 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>
    

    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" />
    
        ...
    

    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)
        }
    }
    

    是的,它甚至需要覆盖 onCreate()onCreateOptionsMenu() .

    PS:这只适用于 android.support.v4.app.Fragmentandroid.support.v7.widget.Toolbar (同样一定要在 styles.xml 中使用 AppCompatActivityAppCompat 主题) .

  • 3

    你的代码很好 . 方法中只缺少super:

    @Override
    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
        // TODO add your menu : 
        inflater.inflate(R.menu.my_menu, menu);
        //TODO call super
        super.onCreateOptionsMenu(menu, inflater);
    }
    
  • 1

    我变得疯狂,因为这里没有任何答案对我有用 .

    To show the menu I had to call: setSupportActionBar(toolbar)

    完成!

    注意:如果您的 toolbar 视图不是't in the same activity layout you can' t直接从您的活动类使用上面的调用,在这种情况下,您需要从您的片段类中获取该活动,然后调用 setSupportActionBar(toolbar) . 记住:您的活动类应该扩展AppCompatActivity .

    希望这个答案对你有所帮助 .

  • 1

    在创建片段视图后设置选项菜单对我来说效果很好 .

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

    我要补充一点,以及它不适合我的原因 .

    它类似于Napster的答案 .

    • Make sure your fragment's hosting activity extends AppCompatActivity, not FragmentActivity!
    public class MainActivity extends AppCompatActivity {
    
    }
    

    来自Google参考Documentation for FragmentActivity:

    注意:如果要实现包含操作栏的活动,则应该使用ActionBarActivity类,它是此类的子类,因此允许您在API级别7及更高级别上使用Fragment API .

    • 要更新Napster的答案 - 现在不推荐使用 ActionBarActivity ,请改用 AppCompatActivity .

    • 使用 AppCompatActivity 时,还要确保将“活动主题设置为 Theme.AppCompat 或类似主题”(Google Doc) .

    注意: android.support.v7.app.AppCompatActivityandroid.support.v4.app.FragmentActivity 类的子类(请参阅AppCompatActivity ref doc) .

  • 2

    在菜单文件夹中创建一个.menu xml文件并添加此xml

    <item
        android:id="@+id/action_search"
        android:icon="@android:drawable/ic_menu_search"
        android:title="@string/action_search"
        app:actionViewClass="android.support.v7.widget.SearchView"
        app:showAsAction="always|collapseActionView" />
    

    在你的片段类中覆盖此方法和

    implement SearchView.OnQueryTextListener    in your fragment class
    
    
    
    @Override
     public void onViewCreated(View view, Bundle savedInstanceState) {    
      super.onViewCreated(view, savedInstanceState);
      setHasOptionsMenu(true);
    
    }
    

    现在只需在fragment类中设置菜单xml文件

    @Override
    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
        inflater.inflate(R.menu.menu_main, menu);
    
        final MenuItem item = menu.findItem(R.id.action_search);
        final SearchView searchView = (SearchView)    
        MenuItemCompat.getActionView(item);
    
    
        MenuItemCompat.setOnActionExpandListener(item,
                new MenuItemCompat.OnActionExpandListener() {
                    @Override
                    public boolean onMenuItemActionCollapse(MenuItem item) {
                        // Do something when collapsed
    
                        return true; // Return true to collapse action view
                    }
    
                    @Override
                    public boolean onMenuItemActionExpand(MenuItem item) {
                        // Do something when expanded
                        return true; // Return true to expand action view
                    }
                });
    
    }
    
  • 44

    如果上述所有方法都不起作用,则需要调试并确保已调用函数onCreateOptionsMenu(通过放置调试或写入日志...)

    如果它没有运行,也许你的Android主题不支持操作栏 . Open AndroidManifest.xml and set the value for android:theme with theme support action bar

    <activity
         android:name=".MainActivity"
         android:label="@string/app_name"
         android:theme="@style/Theme.AppCompat">
    
  • 151

    在你的 onCreate 方法上添加 setHasOptionMenu()

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

    那么 override 你的 onCreateOptionsMenu

    @Override
    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
        menu.add("Menu item")
                .setIcon(android.R.drawable.ic_delete)
                .setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
    }
    

相关问题