如何在不同的片段中更改选项菜单?

16

我有一个带菜单的Fragment:

public class FragmentA extends Fragment {

    public FragmentA() {
        setHasOptionsMenu(true);
    }

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

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

我想更改菜单,但它不起作用,并保留旧的操作菜单。

与上面相同,但使用不同的inflate XML菜单的Fragment B。

public class FragmentB extends Fragment {

    public FragmentB() {
        setHasOptionsMenu(true);
    }

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

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

EDITED:

对于不同的片段,使用不同的菜单布局可能是有用的,对于主活动和不同的ID,则使用1个菜单布局。


2
在构造函数中加入 setHasOptionsMenu(true) - Boban S.
我在onCreate片段中设置了setHasOptionsMenu(true);。你的意思是要放在构造函数里吗?但我没有构造函数。 - alfo888_ibg
请查看 https://stackoverflow.com/a/34597423/905686 - user905686
3个回答

37
在构造函数中放置setHasOptionsMenu(true)并填充特定于片段的菜单。
public class FragmentA extends Fragment {

    public FragmentA() {
       setHasOptionsMenu(true);
    }

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

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

主活动中的菜单

public class MainActivity extends Activity {
    @Override
    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
        inflater.inflate(R.menu.main_menu, menu);
        super.onCreateOptionsMenu(menu, inflater);
    }
}

展开你想要的菜单,主菜单需要在主活动中展开,而特定于片段的菜单需要在片段中展开。 - Boban S.
1
谢谢,它起作用了,我正在使用不同的菜单布局。 - alfo888_ibg
15
在 fragment 的 onCreateOptionsMenu 代码中添加一行 menu.clear(); 后,我的问题得到了解决。 - Alan Nelson
请注意,在构造函数中也不需要调用setHasOptionsMenu(true)。请参见https://stackoverflow.com/a/34597423/905686。 - user905686
请注意,在Fragment中的onCreateOptionsMenu()函数有第二个参数,即MenuInflater。因此,如果您试图从Activity中复制/粘贴该函数,则会出现错误。 - lasec0203

4
可以通过Fragment完成所有操作 - 无需从Activity中填充菜单。
public class UpdateFragment extends Fragment  {

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

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

        inflater.inflate(R.menu.update_menu, menu);
        super.onCreateOptionsMenu(menu, inflater);
    }


    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        int id = item.getItemId();
        switch (id){
            case R.id.navUpdateProfile:
                showToast("navUpdateProfile");
                return true;

            default:
                return super.onOptionsItemSelected(item);
        }
    }
}

0
如果您有多个片段与某些例外情况共享相同的菜单。
  class BaseFragment:Fragment(){
    
    open var menuId = R.menu.default_menu
    
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            setHasOptionsMenu(true) // will apply to all children
        }
        override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
            super.onCreateOptionsMenu(menu, inflater)
            inflater.inflate(menuId, menu) // will apply to all children except for overridden
        }
    override fun onOptionsItemSelected(item: MenuItem): Boolean {
            // all menu ids can be listed here unless specific to code in child
            when (item.itemId) {
                R.id.menu_option_1 -> {
                      // do something
                }
                R.id.menu_option_2 -> {
                    //do something
            }
            return false
        }
    }
    
    class ChildFragment:BasFragment(){
    
 override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            menuId = R.menu.menu_2 // change to a different menu as desired here
        }
    }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接