片段中的onCreateOptionsMenu()不会替换ActionBar菜单

我在我的应用程序中使用NavigationDrawer,并在单击抽屉中的项目时替换片段。 我遇到的问题是,当我更改片段时,ActionBar中的菜单项不会更新。

我已经按照https://www.grokkingandroid.com/adding-action-items-from-within-fragments/紧跟这个教程,但它仍然不适用于我的应用程序。

在这里添加父活动的代码片段和其中一个片段。 我需要的是当初始片段被ContactFormFragment.java替换时,显示联系人表单片段(R.menu.contactform_send_menu)的其他菜单项。

public class MainActivity extends FragmentActivity implements ActionBar.OnNavigationListener {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        setTitle(R.string.app_name);

        // Set up the action bar to show a dropdown list.
        ActionBar actionBar = getActionBar();
        actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_LIST);
        actionBar.setDisplayShowTitleEnabled(true);
        actionBar.setDisplayHomeAsUpEnabled(true);
        actionBar.setHomeButtonEnabled(true);

        createNavigationDrawer(savedInstanceState);
    }

    private final int DRAWER_MAIN = 0;
    private final int DRAWER_CONTACT = 5;

    // update the main content by replacing fragments
    private void selectItem(int position) {
        Fragment fragment = null;
        Bundle args = new Bundle();
        boolean isFragment = false;

        switch (position) {
        case DRAWER_MAIN:
            fragment = new WelcomeSectionFragment();
            args.putString(WelcomeSectionFragment.ITEM_NAME, dataList.get(position).getItemName());
            args.putInt(WelcomeSectionFragment.IMAGE_RESOURCE_ID, dataList.get(position).getImgResID());
            getActionBar().setTitle(R.string.app_name);
            isFragment = true;
            break;
        case DRAWER_CONTACT:
            fragment = new ContactFormFragment();
            args.putString(ContactFormFragment.ITEM_NAME, dataList.get(position).getItemName());
            args.putInt(ContactFormFragment.IMAGE_RESOURCE_ID, dataList.get(position).getImgResID());
            getActionBar().setTitle(R.string.contactform_title);
            isFragment = true;
            break;
        default:
            break;
        }

        if (isFragment) {
            fragment.setArguments(args);
            FragmentManager frgManager = getFragmentManager();
            frgManager.beginTransaction().replace(R.id.content_frame, fragment).commit();

            mDrawerList.setItemChecked(position, true);
            setTitle(dataList.get(position).getItemName());
            mDrawerLayout.closeDrawer(mDrawerList);
        }
    }

}

和片段:

public class ContactFormFragment extends Fragment {

    public ContactFormFragment() {

    }

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

        ca = getActivity();
        Reachability.registerReachability(ca.getApplicationContext());

        settings = ca.getSharedPreferences(Konstanten.PREFERENCES_FILE, 0);
        member = new Gson().fromJson(settings.getString(Konstanten.MEMBER_OBJECT, null), Member.class);

        latoFontLight = Tools.getFont(ca.getAssets(), "Lato-Light.ttf");
        latoFontBold = Tools.getFont(ca.getAssets(), "Lato-Bold.ttf");

        // Update action bar menu items?
        setHasOptionsMenu(true);
    }

    @Override
    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
        // Do something that differs the Activity's menu here
        super.onCreateOptionsMenu(menu, inflater);

        menu.clear();

        if (Build.VERSION.SDK_INT >= 11) {
            // selectMenu(menu);
            inflater.inflate(R.menu.contactform_send_menu, menu);
        }
    }
}

在调试时我可以看到setHasOptionsMenu(true); 在onCreate()中调用,我也进入ContactFormFragment.java的onCreateOptionsMenu()。 我只是不明白为什么操作栏保留其初始菜单项并且不能替换它们。 我错过了什么?

谢谢你的帮助。


尝试把setHasOptionsMenu(true); 在您的ChildFragment.javaonCreateView()内部,我没有在您发布的代码中看到一个。


我得到它的工作! 我遇到的问题是我添加了一个自定义的下拉菜单到主碎片。 所以每次我通过抽屉导航来更改片段时,我都必须手动删除该下拉菜单,并且在返回到主片段时,我将重新添加它。

这是我所做的:

在父母活动中:

MainActivity.java:

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.signin_menu, menu);

    getMenuInflater().inflate(R.menu.clear_search_history_menu, menu);

    // Search
    // Associate searchable configuration with the SearchView
    getMenuInflater().inflate(R.menu.search_menu, menu);
    SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
    SearchView searchView = (SearchView) menu.findItem(R.id.search).getActionView();
    searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName()));

    return super.onCreateOptionsMenu(menu);
}

@Override
public boolean onPrepareOptionsMenu(Menu menu) {
    menu.clear();
    getMenuInflater().inflate(R.menu.signin_menu, menu);
    getMenuInflater().inflate(R.menu.clear_search_history_menu, menu);

    // Search
    // Associate searchable configuration with the SearchView
    getMenuInflater().inflate(R.menu.search_menu, menu);
    SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
    SearchView searchView = (SearchView) menu.findItem(R.id.search).getActionView();
    searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName()));

    // If the nav drawer is open, hide action items related to the content
    // view
    boolean drawerOpen = mDrawerLayout.isDrawerOpen(mDrawerList);
    menu.findItem(R.id.search).setVisible(!drawerOpen);

    return super.onPrepareOptionsMenu(menu);
}

// This is the selection of the drawer (stripped some code to keep it short)
private void selectItem(int position) {
    Fragment fragment = null;
    Bundle args = new Bundle();
    boolean isFragment = false;

    ActionBar actionBar = getActionBar();

    switch (position) {
    case DRAWER_MAIN:
        fragment = new WelcomeSectionFragment();
        actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_LIST);
        actionBar.setListNavigationCallbacks(new GameSystemsAdapter(getActionBarThemedContextCompat(), allSystemsPlusEmpty), this);
        actionBar.setTitle(R.string.app_name);
        isFragment = true;
        break;
    case DRAWER_FAVORITES:
        fragment = new FavoritesMainFragment();
        // Remove System-Select Drop-Down
        actionBar.setListNavigationCallbacks(null, null);
        actionBar.setNavigationMode(0);
        actionBar.setTitle(R.string.favorites);
        isFragment = true;
        break;
    case DRAWER_TOP_MEMBERS:
        fragment = new TopMembersFragment();            
        // Remove System-Select Drop-Down
        actionBar.setListNavigationCallbacks(null, null);
        actionBar.setNavigationMode(0);
        actionBar.setTitle(R.string.top_members_top_helping);
        isFragment = true;
        break;
    default:
        break;
    }

    if (isFragment) {
        fragment.setArguments(args);
        FragmentManager frgManager = getFragmentManager();
        frgManager.beginTransaction().replace(R.id.content_frame, fragment).commit();

        mDrawerList.setItemChecked(position, true);
        setTitle(dataList.get(position).getItemName());
        mDrawerLayout.closeDrawer(mDrawerList);
    }

}

这里是片段的一部分:

ChildFragment.java

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

    if (Build.VERSION.SDK_INT >= 11) {
        selectMenu(menu);
    }
}

@Override
public void onPrepareOptionsMenu(Menu menu) {
    selectMenu(menu);
}

private void selectMenu(Menu menu) {
    parentActivity.getMenuInflater().inflate(R.menu.contactform_send_menu, menu);
}

如果有更好的解决方案,我对你的想法很感兴趣。


有两种情况需要考虑:

  • 你希望所有的行动项目都来自片段。
  • 您也有行动项目,应该是全球性的,并在活动中定义。
  • 让我们从选项2开始,因为这是最常见的情况。

    如果您同时具有特定于片段的项目和全局项目,则不希望在片段中使用onCreateOptionsMenu() 。 原因是它看起来很奇怪 - 即使它有效。 片段操作将在创建片段后立即添加,而全局项目将在抽屉关闭后添加(默认情况下)。 我认为没有用户会喜欢这个。

    你可以做些什么来让片段决定显示哪些项目是为所有要实现的片段创建一个接口。 这可以定义一个方法,该方法将返回菜单的菜单ID进行充气,或者如果没有菜单应该充气,则返回-1

    在选项1的情况下,我只能假设你在Activity的onCreateOptionsMenu() clear()菜单。 否则它不会删除分段的菜单条目。 所以只要摆脱clear() ,一切都应该没问题。

    链接地址: http://www.djcxy.com/p/65361.html

    上一篇: onCreateOptionsMenu() in fragment not replacing ActionBar menus

    下一篇: Retaining old loader after rotation in child activity