博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Android适配底部返回键等虚拟键盘的完美解决方案
阅读量:7065 次
发布时间:2019-06-28

本文共 3967 字,大约阅读时间需要 13 分钟。

 

这个问题来来回回困扰了我很久,一直没能妥善解决。

场景1:华为手机遮挡了屏幕底部。

场景2:进入应用时,虚拟键自动缩回,留下空白区域。

需求:

  • 需要安卓能自适应底部虚拟按键,用户隐藏虚拟按键时应用要占满整个屏幕,当用户启用虚拟键时,应用能往上收缩,等于是被底部虚拟按键顶上来。

  • 需求很简单,实现起来却困难重重。

完美解决方案:

解释一下下面的代码,就是监听某个视图的变化,当可以看见的高度发生变化时,就对这个视图重新布局,保证视图不会被遮挡,也不会浪费屏幕空间。这一点尤其可用在像华为手机等可以隐藏和显示虚拟键盘上导致屏幕变化的手机上。

  • 首先添加工具类AndroidBug54971Workaround
package com.xxxx.xxxx;import android.graphics.Rect;import android.view.View;import android.view.ViewGroup;import android.view.ViewTreeObserver; /** * Created by win7 on 2016/12/14. */ public class AndroidBug54971Workaround { // 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. /** * 关联要监听的视图 * * @param viewObserving */ public static void assistActivity(View viewObserving) { new AndroidBug54971Workaround(viewObserving); } private View mViewObserved;//被监听的视图 private int usableHeightPrevious;//视图变化前的可用高度 private ViewGroup.LayoutParams frameLayoutParams; private AndroidBug54971Workaround(View viewObserving) { mViewObserved = viewObserving; //给View添加全局的布局监听器 mViewObserved.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { public void onGlobalLayout() { resetLayoutByUsableHeight(computeUsableHeight()); } }); frameLayoutParams = mViewObserved.getLayoutParams(); } private void resetLayoutByUsableHeight(int usableHeightNow) { //比较布局变化前后的View的可用高度 if (usableHeightNow != usableHeightPrevious) { //如果两次高度不一致 //将当前的View的可用高度设置成View的实际高度 frameLayoutParams.height = usableHeightNow; mViewObserved.requestLayout();//请求重新布局 usableHeightPrevious = usableHeightNow; } } /** * 计算视图可视高度 * * @return */ private int computeUsableHeight() { Rect r = new Rect(); mViewObserved.getWindowVisibleDisplayFrame(r); return (r.bottom - r.top); } }
  • 然后在你需要解决这个问题的Activity的onCreate方法的setContentView(R.layout.content_frame);后面添加上
setContentView(R.layout.content_frame); AndroidBug54971Workaround.assistActivity(findViewById(android.R.id.content));

如果你看的懂代码,你肯定知道assistActivity方法里放入的View是你 要调整高度的视图。

其他不完美方案:或多或少在某些情况上会起不到作用

我一种方法:

android:fitsSystemWindows=”true” 

这句话写在layout的根目录下,看名字就知道是自适应系统窗口。估计能解决很大一部分手机了,可是在同事的nexus 4下并没有什么用。

第二种方法:

我去掉了每个布局的android:fitsSystemWindows=”true” 

在style文件中添加了这句话。

false
  • 1

注意: 你会发现系统报错,这是因为这句话是在API-19后才有的,所以你可以复制你的style文件,把它放到API-19的文件夹下。这样的用途就是如果手机大于等于API19,就会用API-19的文件夹下的内容。否则用原来的style文件。你在API19文件夹下的style文件的根主题中添加上面这句话就OK啦。

本来我以为是完美解决了我的问题。可是被打脸了。刚进入App时会出现上面的场景2的情况。 

我一看MainActivity中的onCreate方法的setContentView(R.layout.xxxx);之前有下面的代码

//控制底部虚拟键盘        getWindow().getDecorView().setSystemUiVisibility(                View.SYSTEM_UI_FLAG_LAYOUT_STABLE                        | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION                        | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN                        | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION // hide nav bar//                        | View.SYSTEM_UI_FLAG_FULLSCREEN // hide status bar                        | View.SYSTEM_UI_FLAG_IMMERSIVE);

估计是这个项目以前的仁兄为了解决这个问题添加的。

经过多次调试,我添加了一句话

//控制底部虚拟键盘        getWindow().getDecorView().setSystemUiVisibility(                View.SYSTEM_UI_FLAG_LAYOUT_STABLE                        | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION                        | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN                        | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION // hide nav bar//                        | View.SYSTEM_UI_FLAG_FULLSCREEN // hide status bar                        | View.SYSTEM_UI_FLAG_IMMERSIVE);        getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);

场景2的情况解决了。这是在虚拟键一直存在的情况下没有问题了,因为nexus不能手动隐藏虚拟键盘,所以我也不清楚是否能在华为等手机上正常运行。TODO。

另外如果想要一直隐藏虚拟键盘,点击屏幕也不会出现的话,将上面的代码换成:

//让虚拟键盘一直不显示        Window window = getWindow();        WindowManager.LayoutParams params = window.getAttributes();        params.systemUiVisibility = View.SYSTEM_UI_FLAG_HIDE_NAVIGATION|View.SYSTEM_UI_FLAG_IMMERSIVE;        window.setAttributes(params);

转载地址:http://zxxll.baihongyu.com/

你可能感兴趣的文章
TeeChart Pro VCL/FMX教程(一):入门——构建图表
查看>>
微服务架构 SpringCloud(二)Eureka(服务注册和服务发现基础篇)
查看>>
oracle RAC的客户端HA配置
查看>>
VsCode编辑器
查看>>
spring cloud开发、部署注意事项
查看>>
又一款基于BCH开发出来的社交软件BlockPress
查看>>
ttlsa教程系列之mongodb——(五)mongodb架构-复制原理&复制集
查看>>
虚拟主机通过修改.htaccess将入口重定向到public文件夹
查看>>
nginx快速安装
查看>>
Kinect for windows的脸部识别
查看>>
MySQL 运维笔记(一)—— 终止高负载SQL
查看>>
Carrie Higbie:数据中心的绿色布线之道
查看>>
ECS之初体验
查看>>
我的友情链接
查看>>
【风云原创】Flash技术将被Html5枪毙,Silverlight将何去何从?
查看>>
power shell测试wmi
查看>>
话里话外:成功CEO的用人之道——按需激励
查看>>
openwrt无线连接互联网的实现原理【1】
查看>>
WPS for Linux(ubuntu)字体配置(字体缺失解决办法)
查看>>
谷歌为Pwnium***竞赛再掷重金 将提供200万美元奖金
查看>>