全面屏虚拟键适配方案

news/2024/11/28 21:50:54/

写之前先吐槽下自己,工作了这么多年,终于能静下心来写博客了

最近公司有个需求,要实现类似于抖音的小视频全屏播放的样式,当虚拟键盘展示的时候,竖屏视频就撑满整个屏幕,当虚拟键盘隐藏的时候,就需要让视频底部距离屏幕底部有个虚拟键高度的黑边,总结起来就是要保持视频的原始比例,效果如下图:

所以,我们要做的很简单,就是监听NavigationBar的显示和隐藏。

方案一:监听一个全屏 View的高度

之前看到一个思路是,使用addOnGlobalLayoutListener监听一个全屏 View 的高度,然后不停的去检测当前是否展示了 NavigationBar,个人不太喜欢这个方案,有兴趣可以自行查找。

方案二:监听数据库System表字段变化

该方案通过监控settings数据库System表中navigationbar_is_min的变化,来判断当前是否显示虚拟键盘。经过测试,部分手机onChange方法并不会触发。

经过多番查证,问题有两个:

1.原来android5.0之后增加了多用户的特性,虚拟键盘的navigationbar_is_min字段从Settings.db的System表格移到了Global表。

2.不同手机品牌使用的注册字段也不一样。

优化后的方法如下:

  private void initDeviceInfo() {String brand = Build.BRAND;if (brand.equalsIgnoreCase("HUAWEI")) {mDeviceInfo = "navigationbar_is_min";} else if (brand.equalsIgnoreCase("XIAOMI")) {mDeviceInfo = "force_fsg_nav_bar";} else if (brand.equalsIgnoreCase("VIVO")) {mDeviceInfo = "navigation_gesture_on";} else if (brand.equalsIgnoreCase("OPPO")) {mDeviceInfo = "navigation_gesture_on";} else {mDeviceInfo = "navigationbar_is_min";}}
     /*** 注册监听实时监控虚拟键*/private void registerNavigationBarObserver() {if (null == mActivity || !checkDeviceHasNavigationBar()) {return;}if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {mActivity.getContentResolver().registerContentObserver(Settings.System.getUriFor(mDeviceInfo), true, mNavigationBarObserver);} else {mActivity.getContentResolver().registerContentObserver(Settings.Global.getUriFor(mDeviceInfo), true, mNavigationBarObserver);}}private ContentObserver mNavigationBarObserver = new ContentObserver(new Handler()) {@Overridepublic void onChange(boolean selfChange) {if (null == mActivity) {return;}resetVideoHeightByNavigation(checkNavigation());}};

当然,我们注册也不是说所有手机都注册,非全面屏的手机不用注册,所以需要判断一下,但是google 官方提供的检测手机是否有NavigationBar 的方法需要在9.0之后才能用(不是很明白为什么设置 NavigationBar颜色的方法早就有了,但是检测的方法要现在才出╮(╯_╰)╭),所以我们只能另辟蹊径了。
我这里是用检测手机是否存在物理按键的方式来反向判断是否存在虚拟键的,因为全面屏的定义就是去除物理按键,替换为虚拟键。经检测,目前在红米6 pro 上检测不准确,尴尬。。。代码如下:

    /*** 检查设备是否有虚拟键** @return*/public boolean checkDeviceHasNavigationBar() {//通过判断设备是否有返回键、菜单键(不是虚拟键,是手机屏幕外的按键)来确定是否有navigation barboolean hasMenuKey = ViewConfiguration.get(mActivity).hasPermanentMenuKey();boolean hasBackKey = KeyCharacterMap.deviceHasKey(KeyEvent.KEYCODE_BACK);if (!hasMenuKey && !hasBackKey) {// 做任何你需要做的,这个设备有一个导航栏return true;}return false;}

注册完成之后,当触发 onChange 回调时,我们就可以根据当前是否展示了虚拟键盘来做对应的处理了。原理同样是检查settings数据库中字段的变化,但是当你去之前的表中检查时你会发现,在 VIVO 和 OPPO 的手机上永远返回0!!!
呵呵
最后终于查到,是 VIVO 和 OPPO 又移到 Secure 表中!!!什么?你问我那为什么注册的时候能成功?我只能说,不造啊╮(╯_╰)╭
vivo oppo

获取当前虚拟键是否展示的方法:

    /*** 是否展示了 navigationbar** @return*/private boolean checkNavigation() {int navigationBarIsMin = 0;if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {navigationBarIsMin = Settings.System.getInt(mActivity.getContentResolver(),mDeviceInfo, 0);} else {if (Build.BRAND.equalsIgnoreCase("VIVO") || Build.BRAND.equalsIgnoreCase("OPPO")) {navigationBarIsMin = Settings.Secure.getInt(mActivity.getContentResolver(),mDeviceInfo, 0);} else {navigationBarIsMin = Settings.Global.getInt(mActivity.getContentResolver(),mDeviceInfo, 0);}}return navigationBarIsMin != 1;}

最后附上获取虚拟键高度的方法:

    /*** 获取虚拟键的高度** @return*/public int getNavigationBarHeight() {Resources resources = mActivity.getResources();int resourceId = resources.getIdentifier("navigation_bar_height","dimen", "android");//获取NavigationBar的高度int height = resources.getDimensionPixelSize(resourceId);return height;}

没错,你猜对了!这个方法在魅族pro6上有问题!明明是一个没有虚拟键的手机,结果人家非的给你返回了一个高度出来!!!就问你牛不牛!!
魅族

总结:以上方法还需更多的验证和完善,而且该方法均是没考虑刘海屏的情况下。别急,我已经看见产品大佬已经拿着需求向我走来了,祝我平安~
我还能写


http://www.ppmy.cn/news/825682.html

相关文章

html tr加样式,Javascript操作table,tr,td和表格CSS样式设置小常识

效果图:方法一 姓名 性别 住址 电话 张三 男 ... 关于html中table表格tr,td的高度和宽度 做网页的时候经常会遇到各种各样的问题,经常遇到的一个就是会碰到表格宽度对不齐的问题。 .mytab{ bord…

c 语言 合并多个excel,再见Ctrl+C!合并100个Excel表格,只需30秒!

今天考呀呀会计教育小编将学习合并工作表的三种方法,赶紧来看看吧!(由于合并工作表的第一种方法函数法,涉及的函数的应用相对复杂,在函数方面比较薄弱的同学,可以先看第二、三种方法,再继续学习第一种) 各个分表合并到总表——函数流 既然在“拆分”工作表的时候,我们使…

电影院售票系统mysql表格_电影院票务管理系统数据库设计(1)

这两天听到一道面试题:设计一个电影院票务管理系统的表结构。 挺有意思的,我自己也试着做了一做,感觉还是有不少收获的。在本文中我想把做这道题的整个思路重新理一下,也算做个整理了。 现在能得到的需求只有一个:设计一个电影院票务管理系统的表结构。再没有其他信息了,…

vb wps 链接单元格_wps如何超链接wps表格.doc

wps如何超链接wps表格 篇一&#xff1a;Execl WPS批量添加超链接 Excel/WPS表格批量编辑超链接 办公软件Excel和WPS表格中&#xff0c;有时候我们需要编辑大量的超链接&#xff0c;有的我们希望给文字批量添加超链接&#xff0c;有的是希望编辑的网址自动成为超链接。下面通过W…

电脑的一些基础按键

电脑(Computer)是一种利用电子学原理根据一系列指令来对数据进行处理的设备。计算机由运算逻辑单元、控制器、输入和输出设备、记忆单元五大单元组成,以二进制为计算机基本单位。 电脑的一些基础按键 一、电脑中单个键认识与作用: Esc:退出键 Tab:表格键 Caps Lock:大…

计算机考试设置背景音乐,给Excel表格添加背景音乐

平常老是用Excel 来大量处理表格&#xff0c;看久了总让人觉得乏味。如果在编辑Excel2003 表格时能自动播放一些优美的背景音乐那感觉应该很不错吧。本文要介绍的就是这么一种可以简单快速地为Excel2003 表格设置背景音乐的方法。 1. 插入控件 打开要设置背景音乐的Excel 表格文…

运维常用表格

运维常用表格-干货分享

USB协议中HID设备描述符以及键盘按键值对应编码表

前言 这一个表格的主要用途是用于USB设备的开发&#xff0c;例如使用CH552&#xff0c;相关的工程&#xff1a;客制pc小键盘&#xff0c;CH552单片机HID键盘 https://oshwhub.com/TheLight/zi-ding-yi-jian-pan 本码表包含在这一份文档中 链接&#xff1a;https://pan.baidu.…