想全面了解解决方案不妨看下这两篇文章:

https://blog.csdn.net/smileiam/article/details/69055963

https://blog.csdn.net/weixin_38775077/article/details/80980862

解决问题:

1.解决底部按钮或输入框被虚拟导航键遮挡,

2.解决虚拟按键与软键盘冲突

判断是否存在虚拟按键的方法,

一是通过"qemu.hw.mainkeys"判断,=1表示存在虚拟按键,=0表示不存在虚拟按键,该判断适用于虚拟按键中有收起按钮上滑展开的虚拟按键

二是通过获取屏幕真实宽高-可用宽高>0来判断是不是有固定的虚拟按键

public class AndroidBug5497Workaround {private final Activity activity;// For more information, see https://code.google.com/p/android/issues/detail?id=5497// To use this class, simply invoke assistActivity() on an Activity that already has its content view set.public static void assistActivity(Activity activity) {new AndroidBug5497Workaround(activity);}private View mChildOfContent;private int usableHeightPrevious;private FrameLayout.LayoutParams frameLayoutParams;private int statusBarHeight;//状态栏高度private AndroidBug5497Workaround(final Activity activity) {this.activity = activity;if (checkDeviceHasNavigationBar(activity)) {//获取状态栏的高度int resourceId = activity.getResources().getIdentifier("status_bar_height", "dimen", "android");statusBarHeight = activity.getResources().getDimensionPixelSize(resourceId);}//1、找到Activity的最外层布局控件,它其实是一个DecorView,它所用的控件就是FrameLayoutFrameLayout content = (FrameLayout) activity.findViewById(android.R.id.content);//2、获取到setContentView放进去的ViewmChildOfContent = content.getChildAt(0);//3、给Activity的xml布局设置View树监听,当布局有变化,如键盘弹出或收起时,都会回调此监听mChildOfContent.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {//4、软键盘弹起会使GlobalLayout发生变化public void onGlobalLayout() {//5、当前布局发生变化时,对Activity的xml布局进行重绘possiblyResizeChildOfContent(checkDeviceHasNavigationBar(activity));}});//6、获取到Activity的xml布局的放置参数frameLayoutParams = (FrameLayout.LayoutParams)mChildOfContent.getLayoutParams();}/*** 重新调整布局高度* 获取界面可用高度,如果软键盘弹起后,Activity的xml布局可用高度需要减去键盘高度** @param hasNav*/private void possiblyResizeChildOfContent(boolean hasNav) {//1、获取当前界面可用高度,键盘弹起后,当前界面可用布局会减少键盘的高度int usableHeightNow = computeUsableHeight(hasNav);//2、如果当前可用高度和原始值不一样if (usableHeightNow != usableHeightPrevious) {//3、获取Activity中xml中布局在当前界面显示的高度int usableHeightSansKeyboard;if (hasNav)usableHeightSansKeyboard = mChildOfContent.getHeight();//兼容华为等机型else {usableHeightSansKeyboard = mChildOfContent.getRootView().getHeight();//这个判断是为了解决19之前的版本不支持沉浸式状态栏导致布局显示不完全的问题if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {Rect frame = new Rect();activity.getWindow().getDecorView().getWindowVisibleDisplayFrame(frame);int statusBarHeight = frame.top;usableHeightSansKeyboard -= statusBarHeight;}}//4、Activity中xml布局的高度-当前可用高度int heightDifference = usableHeightSansKeyboard - usableHeightNow;//5、高度差大于屏幕1/4时,说明键盘弹出if (heightDifference > (usableHeightSansKeyboard / 4)) {// keyboard probably just became visible// 6、键盘弹出了,Activity的xml布局高度应当减去键盘高度if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT && hasNav) {frameLayoutParams.height = usableHeightSansKeyboard - heightDifference + statusBarHeight;} else {frameLayoutParams.height = usableHeightSansKeyboard - heightDifference;}} else {if (hasNav)frameLayoutParams.height = usableHeightNow + statusBarHeight;elseframeLayoutParams.height = usableHeightSansKeyboard;}//7、 重绘Activity的xml布局mChildOfContent.requestLayout();usableHeightPrevious = usableHeightNow;}}/*** 计算mChildOfContent可见高度 ** @return*/private int computeUsableHeight(boolean hasNav) {if (hasNav) {Rect r = new Rect();mChildOfContent.getWindowVisibleDisplayFrame(r);// 全屏模式下:直接返回r.bottom,r.top其实是状态栏的高度if (r.top < statusBarHeight)return r.bottom - statusBarHeight;elsereturn r.bottom - r.top;} else {Rect frame = new Rect();activity.getWindow().getDecorView().getWindowVisibleDisplayFrame(frame);int statusBarHeight = frame.top;Rect r = new Rect();mChildOfContent.getWindowVisibleDisplayFrame(r);//这个判断是为了解决19之后的版本在弹出软键盘时,键盘和推上去的布局(adjustResize)之间有黑色区域的问题if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {return (r.bottom - r.top) + statusBarHeight;}return (r.bottom - r.top);}}/*** 通过"qemu.hw.mainkeys"判断是否存在NavigationBar** @return 是否有NavigationBar*/private static boolean checkDeviceHasNavigationBar(Activity activity) {boolean hasNavigationBar = false;Resources rs = activity.getResources();int id = rs.getIdentifier("config_showNavigationBar", "bool", "android");if (id > 0) {hasNavigationBar = rs.getBoolean(id);}try {Class systemPropertiesClass = Class.forName("android.os.SystemProperties");Method m = systemPropertiesClass.getMethod("get", String.class);String navBarOverride = (String) m.invoke(systemPropertiesClass, "qemu.hw.mainkeys");if ("1".equals(navBarOverride)) {hasNavigationBar = false;} else if ("0".equals(navBarOverride)) {hasNavigationBar = true;} else {hasNavigationBar = hasNavBar(activity);}} catch (Exception e) {}return hasNavigationBar;}/*** 根据屏幕真实宽高-可用宽高>0来判断是否存在NavigationBar** @param activity 上下文* @return 是否有NavigationBar*/private static boolean hasNavBar(Activity activity) {WindowManager windowManager = activity.getWindowManager();Display d = windowManager.getDefaultDisplay();DisplayMetrics realDisplayMetrics = new DisplayMetrics();if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {d.getRealMetrics(realDisplayMetrics);}int realHeight = realDisplayMetrics.heightPixels;int realWidth = realDisplayMetrics.widthPixels;DisplayMetrics displayMetrics = new DisplayMetrics();d.getMetrics(displayMetrics);int displayHeight = displayMetrics.heightPixels;int displayWidth = displayMetrics.widthPixels;return (realWidth - displayWidth) > 0 || (realHeight - displayHeight) > 0;}
}

Android适配页面底部虚拟按键相关推荐

  1. Android适配页面底部虚拟按键,解决与软键盘冲突,AndroidBug5497Workaround

    想全面了解解决方案不妨看下这两篇文章: https://blog.csdn.net/smileiam/article/details/69055963 https://blog.csdn.net/we ...

  2. android 隐藏手机底部虚拟按键

    今天,简单讲讲android如何隐藏手机下面的虚拟按键. 其实,自己在做界面适配时,老是发现了华为手机存在适配的问题,主要就是华为手机有一个底部的虚拟按键占用了界面的部分空间,所以在网上搜索了如何隐藏 ...

  3. Android如何隐藏底部虚拟按键

    虚拟按键隐藏 相信大家在做屏幕适配时候,会对虚拟按键问题或多或少有一些疑问,接下来带给大家解决虚拟按键的方法. android隐藏底部虚拟键Navigation Bar实现全屏 安卓4.1之后为全虚拟 ...

  4. android华为隐藏底部虚拟按键,沉浸式状态栏/华为虚拟按键隐藏

    19版本以上Android可以自己实现沉浸式状态栏的设置 1.创建values-v21文件夹(为了匹配低版本) 在style文件中设置: 设置了这两个属性状态栏就能设置为透明的.但是需要注意的是,这个 ...

  5. 这是最简单解决Android适配之【虚拟按键遮挡布局】

    最近开发项目有个适配的小问题,在用android studio 开发程序的时候发现一个问题,虚拟按键会遮挡布局,在6.0.1的系统中虚拟按键会挡住布局,特别是华为手机和小米底部会有虚拟按键等,而在6. ...

  6. 【Android】隐藏底部虚拟按键

    Google的官方文档是: https://developer.android.com/training/system-ui/navigation.html#behind 示例代码 1 View de ...

  7. android 华为底部虚拟键盘隐藏,Android隐藏手机底部虚拟按键的方法

    现在的Android手机有好多底部带虚拟按键,比如华为.nexus.魅族等等,一般情况下对APP没啥影响,但是有时候就必须要强制隐藏. 例如:游戏的时候,拍照的时候. 接下来加上几个方法就OK 了,代 ...

  8. 【Android】隐藏底部虚拟按键,亲测可用

    Google的官方文档是: https://developer.android.com/training/system-ui/navigation.html#behind 示例代码 View deco ...

  9. Android适配华为手机虚拟按键显示或隐藏

    华为的一些手机的屏幕上的虚拟按键是可以显示或者隐藏的,因此在布局适配的时候就要考虑到这个问题,要不然当虚拟按键被隐藏后界面的布局就会出现问题,下面给出一种解决方法,(原文来自:安卓适配碰到的一些问题) ...

最新文章

  1. you may be a victim of software counterfeiting 的解药(亲自验证过方法2)
  2. JavaScript定义函数的几种方式 1
  3. 我做产品的三大思维:发散、纵横和表里(上)
  4. Linux shell的和||
  5. python浓缩(14)执行环境
  6. clamav Java_ClamAV安装使用及API例子
  7. DHAT:动态堆分析工具
  8. java编译生成哪些文件_java编译后生成什么文件?生成的文件包括什么?
  9. Linux下C++静态库、动态库的制作与使用
  10. 使用Node.js制作爬虫教程
  11. idea maven 删除dependencies_使用IDEA创建Maven工程 创建javase工程
  12. python整数类型与数学-Python类型和运算--数字
  13. signature=70706aa92e6532c935fb1dce5adc16b3,Thunder signatures
  14. redhat linux raid5,Linux 红帽   磁盘管理~~~~RAID5+LVM
  15. CRF模型——打通crf模型的任督二脉(一)
  16. 三种迷宫算法(深度优先、随机Prim、递归分割)
  17. 18-基于STM32的室内可见光通信系统设计
  18. 编译原理实验三 TINY语法分析器
  19. Dev++ 环境设置C语言关键字显示颜色
  20. win10系统开启IIS服务

热门文章

  1. Orange1.0开发日记(1)
  2. nodejs之express小记
  3. Blog1 TCMKG——中医药知识图谱项目介绍
  4. 黑河师范学院计算机怎么样,黑河学院是几本 学生评价怎么样好不好(10条)
  5. 微信小程序正则验证手机号、邮箱及错误提示
  6. 【Java/总结/牛客/ACM赛制】 “中国东信杯”广西大学第四届程序设计竞赛(同步赛)
  7. IPad实现Mac的分屏功能
  8. 如何在 iPhone 和 iPad 上关闭照片的地理标记
  9. 验证可用的ESP32/8266配网方式,开源代码,web配网,smartconfig配网
  10. Speedoffice(word)文档如何插入表格