从外部片段内的 Fragment TabHost 的子片段添加新的选项菜单

Add new option menu from child fragment of FragmentTabHost inside outer fragment

当我为我的应用程序使用一些嵌套片段时,应用程序的子片段无法通过覆盖 onCreateOptionsMenu(Menu menu, MenuInflater menuInflater) 方法(永远不要点击此方法)来添加新的选项菜单。

Class应用层级如下。

MainActivity.java(扩展 SherlockFragmentActivity) (MainActivity 包括以下子片段)

  1. Fragment1.java(扩展 SherlockFragment)

  2. Fragment2.java(扩展 SherlockFragment)

(Fragment2 包括用于添加以下子片段的 FragmentTabHost)

 i. ChildFragment1.java(extends SherlockFragment)

 ii. ChildFragment2.java(extends SherlockFragment)

 iii. ChildFragment3.java(extends SherlockFragment)

我可以通过在 onCreate(Bundle savedInstanceState) 中添加 setHasOptionsMenu(true) 和 通过覆盖 onCreateOptionsMenu(Menu menu, MenuInflater menuInflater)

但是我无法在 ChildFragment1、ChildFragment2、ChildFragment3 中添加新的 OptionMenu,因为永远不会调用子片段 类 的 onCreateOptionsMenu(Menu menu, MenuInflater menuInflater) 方法。

您必须手动调用该方法。在您的 Fragment2 中实施以下

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

@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
    super.onCreateOptionsMenu(menu, inflater);
    ChildFragment frag = (ChildFragment) getChildFragmentManager().findFragmentBy...;
    if (frag != null) frag.inflateOptionsMenu(menu, new MenuInflater(mActivity));
}

在你的ChildFragment然后有

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

public void inflateOptionsMenu(Menu menu, MenuInflater inflater) {
    onCreateOptionsMenu(menu, inflater);
}

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

我在 chat folloing this question 中找到了解决方案。

现在可以调用子fragment的onCreateOptionsMenu,也可以通过下面的代码调用onOptionsItemSelected

Fragment2.java

protected FragmentTabHost mTabHost;

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

@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater menuInflater) {
    super.onCreateOptionsMenu(menu, menuInflater);
    Fragment currentFragment = getChildFragmentManager().findFragmentByTag(mTabHost.getCurrentTabTag());
    if (currentFragment != null && currentFragment instanceof BaseTabsPagerChildFragment)
        ((BaseTabsPagerChildFragment) currentFragment).inflateOptionsMenu(menu, menuInflater);
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    if (super.onOptionsItemSelected(item)) {
        return true;
    } else {
        Fragment currentFragment = getChildFragmentManager().findFragmentByTag(mTabHost.getCurrentTabTag());
        if (currentFragment != null && currentFragment instanceof BaseTabsPagerChildFragment) {
            return ((BaseTabsPagerChildFragment) currentFragment).onOptionsItemSelected(item);
        }
    }
    return false;
}

BaseTabsPagerChildFragment.java

abstract class BaseTabsPagerChildFragment extends BaseSherlockFragment {
    public abstract void inflateOptionsMenu(Menu menu, MenuInflater menuInflater);
}

ChildFragment1.java(扩展 BaseTabsPagerChildFragment.java)

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

@Override
public void inflateOptionsMenu(Menu menu, MenuInflater menuInflater) {
    onCreateOptionsMenu(menu, menuInflater);
}

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

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    boolean handled = super.onOptionsItemSelected(item);
    if (handled) {
        return true;
    }
    int itemId_ = item.getItemId();
    if (itemId_ == R.id.menu_item_compose) {
        launchCompose();
        return true;
    }
    if (itemId_ == R.id.menu_item_delete) {
        doDelete();
        return true;
    }
    return false;
}

谢谢。