首页 > 其他分享 >Android Menu 回调

Android Menu 回调

时间:2022-12-09 19:57:28浏览次数:32  
标签:sHasPermanentMenuKey false Menu openPanel config Android 回调 true android

先看错错误,使用openOptionsMenu() 的时候onMenuVisibilityChanged 没有回调 , 到真机跑了跑确是有回调的

取了下小米的堆栈信息

这里先贴下调用流程:

Activity.openOptionsMenu() -- >  mWindow.openPanel(Window.FEATURE_OPTIONS_PANEL, null) 

Activity.onMenuOpened() -->  ActionBar.dispatchMenuVisibilityChanged(true) --> onMenuVisibilityChanged(true)

发现小米走的是函数showOverflowMenu()

at com.android.internal.widget.ActionBarOverlayLayout.showOverflowMenu(ActionBarOverlayLayout.java:790)
at com.android.internal.policy.PhoneWindow.openPanel(PhoneWindow.java:787)
    @Override
    public final void openPanel(int featureId, KeyEvent event) {
        if (featureId == FEATURE_OPTIONS_PANEL && mDecorContentParent != null &&
                mDecorContentParent.canShowOverflowMenu() &&
                !ViewConfiguration.get(getContext()).hasPermanentMenuKey()) {
            // 没有hasPermanentMenuKey() 即没有永久菜单按键,物理按键
            mDecorContentParent.showOverflowMenu();   //很明显小米走这里了
        } else {
            openPanel(getPanelState(featureId, true), event);
        }
    }

而我的设备走的openPanel(), 虽然openPanel里也有 onMenuOpened 回调

不过featureid不对,我们穿入的是 FEATURE_OPTIONS_PANEL ,onMenuOpened只有当是FEATURE_ACTION_BAR才会处理

    // 
    private void openPanel(final PanelFeatureState st, KeyEvent event) {
        ...
        Callback cb = getCallback();
        if ((cb != null) && (!cb.onMenuOpened(st.featureId, st.menu))) {
            // Callback doesn't want the menu to open, reset any state
            closePanel(st, true);
            return;
        }
    }

    //frameworks/base/core/java/android/app/Activity.java
    public boolean onMenuOpened(int featureId, Menu menu) {
        if (featureId == Window.FEATURE_ACTION_BAR) {
            initWindowDecorActionBar();
            if (mActionBar != null) {
                mActionBar.dispatchMenuVisibilityChanged(true);
            } else {
                Log.e(TAG, "Tried to open action bar menu with no action bar");
            }
        }
        return true;
    }

回到主题,最后发现是hasPermanentMenuKey()函数返回了true导致

public boolean hasPermanentMenuKey() {
    return sHasPermanentMenuKey;
}

// android.view.ViewConfiguration
private ViewConfiguration(Context context) {
       ...
       if (!sHasPermanentMenuKeySet) { // 只执行一次
            // 配置在frameworks/base/core/res/res/values/config.xml
            final int configVal = res.getInteger(
                    com.android.internal.R.integer.config_overrideHasPermanentMenuKey);
 
            switch (configVal) {
                default:
                case HAS_PERMANENT_MENU_KEY_AUTODETECT: { //没有特殊配置,默认走这
                    IWindowManager wm = WindowManagerGlobal.getWindowManagerService();
                    try {
                        //这赋值
                        sHasPermanentMenuKey = !wm.hasNavigationBar(context.getDisplayId());
                        sHasPermanentMenuKeySet = true;
                    } catch (RemoteException ex) {
                        sHasPermanentMenuKey = false;
                    }
                }
                break;
                case HAS_PERMANENT_MENU_KEY_TRUE:
                    sHasPermanentMenuKey = true;
                    sHasPermanentMenuKeySet = true;
                    break;

                case HAS_PERMANENT_MENU_KEY_FALSE:
                    sHasPermanentMenuKey = false;
                    sHasPermanentMenuKeySet = true;
                    break;
            }
        }
}

PhoneWindowManager.hasNavigationBar() 读取了属性配置config_showNavigationBarqemu.hw.mainkeys 属性 ,

总结:
如果qemu.hw.mainkeys=1,则 mHasNavigationBar=false sHasPermanentMenuKey=true

如果qemu.hw.mainkeys=0,则 mHasNavigationBar=true sHasPermanentMenuKey=false

如果qemu.hw.mainkeys=null,则 mHasNavigationBar=config_showNavigationBar sHasPermanentMenuKey=!config_showNavigationBar

// frameworks/base/services/core/java/com/android/server/policy/PhoneWindowManager.java
    @Override
    public void setInitialDisplaySize(Display display, int width, int height, int density) {
        ...
        // <bool name="config_showNavigationBar">false</bool> 我的设备是false
        mHasNavigationBar = res.getBoolean(com.android.internal.R.bool.config_showNavigationBar);

        // Allow a system property to override this. Used by the emulator.
        // See also hasNavigationBar().
        String navBarOverride = SystemProperties.get("qemu.hw.mainkeys");
        if ("1".equals(navBarOverride)) {
            mHasNavigationBar = false;
        } else if ("0".equals(navBarOverride)) {
            mHasNavigationBar = true;
        }
        ...
}

我的设备配置qemu.hw.mainkeys ,配置为0后 ,恢复正常 如果不想显示NavigationBar,把config_showNavigationBar设置成2

标签:sHasPermanentMenuKey,false,Menu,openPanel,config,Android,回调,true,android
From: https://www.cnblogs.com/tangshunhui/p/16969674.html

相关文章

  • 最强 Android Studio 使用小技巧和快捷键总结
    写在前面本文翻译自 AndroidStudioTipsbyPhilippeBreault,一共收集了62个AndroidStudio使用小技巧和快捷键。根据这些小技巧的使用场景,本文将这62个小技巧分为常用......
  • 解决下载Android源码时遇到的 download error
    我下载和编译环境ubuntu12.0464位lenovothinkpadi32G最近要做android的浏览器插件要用到android的源码参与编译(不是指framework层源码)按照google的官网设......
  • Android UI布局 —— 仿QQ登录界面(转载)
    ​最近,有点空闲的时间就拿QQ登录界面来模仿练手,做了个简单的登录界面。界面一般般吧,不算很漂亮,现在拿出来分享,希望大家一起学习与进步。有什么不足之处,请各位大侠多多......
  • 让Android设备永不锁屏(转载)
    锁定屏幕对于移动终端来说是非常有必要的,但是对于机顶盒产品就没有这个必要了。所以本文介绍一下怎样让Android设备永不锁屏。    Android系统的锁屏时间存放在Settin......
  • mac环境下Android 反编译
    一、需要的工具apktool:反编译APK文件,得到classes.dex文件,同时也能获取到资源文件以及布局文件。dex2jar:将反编译后的classes.dex文件转化为.jar文件。jd-gui:用于将.jar文件......
  • Android 轻量级存储方案的前世今生【SharedPreferences、MMKV、Jetpack DataStore】
    背景对于Android轻量级存储方案,有大多数人都很熟悉的SharedPreferences;也有基于mmap的高性能组件MMKV,底层序列化/反序列化使用protobuf实现,性能高,稳定性强;还有Jetp......
  • 基于Android的校园二手闲置物品交易系统设计与实现
    OverridetheentrypointofanimageIntroducedinGitLabandGitLabRunner9.4.Readmoreaboutthe extendedconfigurationoptions.Beforeexplainingtheav......
  • Android插件化动态加载APK
    什么是插件化动态加载apk?支付宝是万能的,既可以淘票票看电影,又可以买车票,还可以开共享单车,这些都是支付宝的开发人员开发维护的么?显然不是,那么他是怎么做到的呢?是使用了动态......
  • android webview设置自适应任意大小的pc网页
    1.Android:WebView如何设定支持缩放:需要对WebView和WebSettings做一下设定2.WebSettingswebSettings=view.getSettings();3.webSettings.setJavaScriptEnabled(......
  • Android截屏截图的几种方法总结
    Android截屏Android截屏的原理:获取具体需要截屏的区域的Bitmap,然后绘制在画布上,保存为图片后进行分享或者其它用途一、Activity截屏1、截Activity界面(包含空白的状态栏)/......