OptionsMenu仅在Android 4.1上打开一次

时间:2013-08-29 14:53:53

标签: android android-optionsmenu

我正在使用此代码打开一个选项菜单作为弹出窗口:

@Override
public boolean onPrepareOptionsMenu(Menu menu){
    openMenu();
    return true;
}

private void openMenu(){
    View popUpView = getLayoutInflater().inflate(R.layout.menu, null);
    popUpMenu = new PopupWindow(popUpView, LayoutParams.FILL_PARENT
                                        , LayoutParams.WRAP_CONTENT
                                        , true);
    popUpMenu.setBackgroundDrawable(new BitmapDrawable());
    popUpMenu.setAnimationStyle(android.R.style.Animation_Dialog);
    popUpMenu.showAtLocation(popUpView, Gravity.BOTTOM, 0, 0);
    makePopUpMenuButtons(popUpView);
}

问题是,在Android 4.1上菜单只打开一次。 我读了一些关于invalidateOptionsMenu()的内容,但我不知道在哪里实现这个方法。另外eclipse说“方法invalidateOptionsMenu()没有在...上定义。”。

是否有人知道如何操作,以便每次点击菜单按钮时都会打开选项菜单?

修改

我不使用android菜单对象,因为我想要一个自定义设计。这就是为什么我在onPrepareOptionsMenu中创建一个popop的原因。所以我不使用onOptionsItemSelected。我的问题是onPrepareOptionMenu仅在第一次点击时被调用,之后只是不规则。

  

在Android 3.0及更高版本中,当操作栏中显示菜单项时,选项菜单被视为始终打开。当事件发生并且您想要执行菜单更新时,必须调用invalidateOptionsMenu()以请求系统调用onPrepareOptionsMenu()。

这段话说我必须在我的API为3.0及更高版本时调用invalidateOptionsMenu。但是在我的项目中,一切都可以正常使用低于4.1的API。我在显示弹出窗口后尝试调用invalidateOptionsMenu,但是eclipse发出错误,因为该方法未定义...

3 个答案:

答案 0 :(得分:3)

以下将使事情变得更加清晰:

<强> 1。 onCreateOptionsMenu()

要指定活动的选项菜单,请覆盖onCreateOptionsMenu()。在此方法中,您可以将菜单资源(在XML中定义)扩展到回调中提供的菜单中。 对于Android 2.3.x and lower,当用户第一次打开菜单时,系统会调用onCreateOptionsMenu()来创建选项菜单。但是对于Android 3.0 and higher,系统会在启动活动时调用onCreateOptionsMenu(),以便向操作栏显示项目。

系统调用onCreateOptionsMenu()后,它会保留您填充的菜单实例,除非由于某种原因导致菜单失效,否则不会再次调用onCreateOptionsMenu()。但是,您应该仅使用onCreateOptionsMenu()来创建初始菜单状态,而不是在活动生命周期中进行更改。

<强> 2。 onOptionsItemSelected()

当您从选项菜单中选择项目时,系统会调用您的活动onOptionsItemSelected()方法。这个方法传递了选中的MenuItem。

第3。 onPrepareOptionsMenu()

如果要根据活动生命周期中发生的事件修改选项菜单,可以使用onPrepareOptionsMenu()方法执行此操作。此方法会传递Menu对象,因为它当前存在,因此您可以对其进行修改,例如添加,删除或禁用项目。

Android 2.3.x and lower上,每次用户打开选项菜单(按菜单按钮)时,系统都会调用onPrepareOptionsMenu()

Android 3.0 and higher上,当操作栏中显示菜单项时,选项菜单被视为始终打开。当事件发生且您想要执行菜单更新时,您必须致电invalidateOptionsMenu()以请求系统调用onPrepareOptionsMenu()

invalidateOptionsMenu() Refer this

onPrepareOptionsMenu() Refer this

因此您可以尝试如下:

为了处理向后兼容性,请在您的活动中添加以下内容。

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
        case R.id.Menu1:
            refreshMenu();
            break;
        case R.id.Menu2:
            refreshMenu();
            break;     
        }
        return super.onOptionsItemSelected(item);
    }

   public void refreshMenu() {
      if (Build.VERSION.SDK_INT >= 11) {
          invalidateOptionsMenu();
      }
   }

您还可以refer this

答案 1 :(得分:1)

    @Override
    public boolean onPrepareOptionsMenu(Menu menu){
        //You need to pass the menu to open menu method
        openMenu(menu);
        return true;
    }
    //
    private void openMenu(Menu menu){
        //that menu can not be null
        View popUpView = getLayoutInflater().inflate(R.layout.menu, menu);
        popUpMenu = new PopupWindow(popUpView, LayoutParams.FILL_PARENT
                                            , LayoutParams.WRAP_CONTENT
                                            , true);
        popUpMenu.setBackgroundDrawable(new BitmapDrawable());
        popUpMenu.setAnimationStyle(android.R.style.Animation_Dialog);
        popUpMenu.showAtLocation(popUpView, Gravity.BOTTOM, 0, 0);
        makePopUpMenuButtons(popUpView);

}

尝试option menu

在第二个查询的上方链接中阅读在运行时更改菜单项段落

修改

@Override
    public boolean onPrepareOptionsMenu(Menu menu) {
        // TODO Auto-generated method stub

        menu.clear();

        menu.add(0, MENU_Unsubscribe, Menu.NONE, "Pop UP");

        return super.onPrepareOptionsMenu(menu);
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // TODO Auto-generated method stub

        if (item.getItemId() == MENU_Unsubscribe) {
            View popUpView = getLayoutInflater().inflate(R.layout.activity_new,
                    null);

            btnOK=(Button)popUpView.findViewById(R.id.btnOK);



            popUpMenu = new PopupWindow(popUpView,
                    LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT, false);
//          popUpMenu.setBackgroundDrawable
            popUpMenu.setAnimationStyle(android.R.style.Animation_Dialog);
            popUpMenu.showAtLocation(popUpView, Gravity.CENTER, 0, 0);
            popUpMenu.setOutsideTouchable(true);

            btnOK.setOnClickListener(new OnClickListener() {

                @Override
                public void onClick(View v) {
                    // TODO Auto-generated method stub
                    popUpMenu.dismiss();
                }
            });

        }

        return super.onOptionsItemSelected(item);
    }

答案 2 :(得分:0)

这段代码解决了我的问题:

@Override
public boolean onKeyUp(int keyCode, KeyEvent event) {
    if(keyCode == KeyEvent.KEYCODE_MENU) {
        openMenu();
        return true;
    }
    return super.onKeyUp(keyCode, event);
}

private void openMenu(){
    View popUpView = getLayoutInflater().inflate(R.layout.menu, null);
    popUpMenu = new PopupWindow(popUpView, LayoutParams.FILL_PARENT
                                        , LayoutParams.WRAP_CONTENT
                                        , true);
    popUpMenu.setBackgroundDrawable(new BitmapDrawable());
    popUpMenu.setAnimationStyle(android.R.style.Animation_Dialog);
    popUpMenu.showAtLocation(popUpView, Gravity.BOTTOM, 0, 0);
    makePopUpMenuButtons(popUpView);
}

但我不知道这是否是最好的方式