1

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

@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 中创建弹出窗口的原因。所以我不使用onOptionsItemSelected。我的问题是 onPrepareOptionMenu 仅在第一次单击时被调用,之后才不规则。

在 Android 3.0 及更高版本上,当菜单项出现在操作栏中时,选项菜单被认为始终处于打开状态。当事件发生并且您想要执行菜单更新时,您必须调用 invalidateOptionsMenu() 来请求系统调用 onPrepareOptionsMenu()。

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

4

3 回答 3

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 对象,以便您可以对其进行修改,例如添加、删除或禁用项目。

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

在 上Android 3.0 and higher,当菜单项出现在操作栏中时,选项菜单被认为始终处于打开状态。当事件发生并且您想要执行菜单更新时,您必须调用invalidateOptionsMenu()系统调用来请求onPrepareOptionsMenu()

参考invalidateOptionsMenu() 这个

参考onPrepareOptionsMenu() 这个

因此,您可以尝试如下:

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

    @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();
      }
   }

你也可以参考这个

于 2013-08-29T15:58:29.033 回答
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);

}

尝试选项菜单

阅读上面链接中的运行时更改菜单项段落以进行第二次查询

编辑:

@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);
    }
于 2013-08-29T15:01:36.783 回答
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);
}

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

于 2013-08-30T14:25:50.780 回答