23

我的应用程序中有操作栏。我正在使用 menu.xml 添加操作项。我使用 action bar-compat 作为我的支持库。我观察到一个奇怪的问题,即我的操作项被重复。

当我的设备闲置或使用其他应用程序时,我随机发现了这个问题。请在下面找到屏幕截图和我的代码:

private LoginWebActivity mContext;
private final String TAG = "LoginFragment";

// for metrics
private String mPageNameSignIn = "signin";

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    mView = inflater.inflate(R.layout.webview, container, false);

    return mView;
}

@Override
public void onActivityCreated(Bundle savedInstanceState) {
    super.onActivityCreated(savedInstanceState);
    mContext = (LoginWebActivity) getActivity();
    initFragment();

}

@Override
public void onResume() {

    super.onResume();
}

/**
 * Initialises the views and variables of the fragment.
 */
@SuppressLint({ "JavascriptInterface", "SetJavaScriptEnabled" })
protected void initFragment() {


    mWebView = (WebView) mView.findViewById(R.id.webView);
    Bundle b = mContext.getIntent().getExtras();
    if (b != null) {
        mUrl = b.getString(Constants.EXTRA_WEB_LOGIN_URL);
    }
    super.initFragment();

    setHasOptionsMenu(true);
}

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

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    // Navigate
    switch (item.getItemId()) {
    case R.id.menu_item_signup:
        mContext.onSignUpClick();
        break;
    case android.R.id.home:
        if (!goBack())
            getActivity().finish();
    default:
        break;
    }
    return super.onOptionsItemSelected(item);
}

我的 XML:

<?xml version="1.0" encoding="utf-8"?>

<item
    android:id="@+id/menu_item_signup"
    allergy:showAsAction="ifRoom"
    android:title="@string/sign_up">
</item>

在此处输入图像描述

4

5 回答 5

68

在添加项目之前,您必须清除您的菜单对象。我遇到了同样的问题,这是我找到的最佳解决方案。

@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
    menu.clear();
    inflater.inflate(R.menu.signin, menu);
    super.onCreateOptionsMenu(menu, inflater);
}
于 2013-12-04T09:27:52.337 回答
25

这个聚会很晚了,但是对于像我一样通过谷歌遇到这个问题的人来说,这才是真正的问题。

您没有发布创建片段的活动代码,但我敢猜测它看起来像这样:

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_layout);
        Fragment fragment = ...
        getSupportFragmentManager()
            .beginTransaction()
            .add(R.id.fragment_container, fragment)
            .commit();
    }

这样做的问题是,当活动经历其生命周期时(如您所说,“当我的设备空闲或与其他应用程序一起工作时会发生这种情况”),系统将为您保存和恢复片段的状态。但是使用此代码,您还向 Activity 添加了一个新片段,因此您最终会在 Activity 中运行多个片段,每个片段都向菜单添加一个项目。

虽然发布的解决方法将解决重复的菜单条目问题,但它会留下这些额外的片段实例,这显然不是你想要的。

正确的修复是一个简单的空检查:

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_layout);

        if (savedInstanceState == null) {
            Fragment fragment = ...
            getSupportFragmentManager()
                .beginTransaction()
                .add(R.id.fragment_container, fragment)
                .commit();
        }
    }

由于系统将使用 savedInstanceState 参数的非空 Bundle 指示正在重新创建活动,因此您检查它以确定是否应该创建和添加新片段。

希望有帮助。

于 2015-01-20T19:04:51.683 回答
4

我使用了 Renan Bandeira 的出色解决方案,但我遇到了一些错误,所以我对其进行了一些更改,并且也为我工作。然后我分享我的经验:也许它再次变得有帮助,所有的功劳都归功于他的伟大解决方案。

@Override
    public void onCreateOptionsMenu(Menu menu ) {
       menu.clear();
       MenuInflater inflater = getMenuInflater();    
       inflater.inflate(R.menu."your current activity name ", menu);
    return true;
}
于 2014-07-01T12:29:13.107 回答
2

我面临同样的问题,并且与@Szymon 的状态完全相同“我从片段中添加菜单选项,我创建了多个片段?” 所以我的解决方案如下所示。

创建:

@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
    menu.clear();
    inflater.inflate(R.menu.menu, menu);
    menu.findItem(R.id.action_one).setVisible(true);
    menu.findItem(R.id.action_two).setVisible(false);
    super.onCreateOptionsMenu(menu, inflater);
}

准备:

@Override
public void onPrepareOptionsMenu(Menu menu) {
    if (isAdded()
            && !isDetached()
            && isVisible()
            && !isRemoving()
            )
    {
        // show the menu
        if (menu.findItem(R.id.action_one).isVisible())
            menu.findItem(R.id.action_one).setVisible(true);
        // hide the menu
        if (menu.findItem(R.id.action_two).isVisible())
            menu.findItem(R.id.action_two).setVisible(false);
    }
}
于 2015-09-09T18:37:08.620 回答
0

您应该改用以下方法,您将不会再看到重复项(请注意,它只有一个 Menu 对象作为参数)

  @Override
    public boolean onCreateOptionsMenu( Menu menu )
    {
        getMenuInflater().inflate( R.menu.main_activity_menu, menu );
        return true;
    }
于 2015-09-18T16:55:50.880 回答