安卓输入框被虚拟键盘挡住的问题(微信开发)
作者:余小弟 发布时间:2023-12-01 15:42:43
先通过一个页面看下事情的来龙去脉,页面如下所示:
这个页面刚好一屏幕大小,所以没有滚动条,因为“保存”键上面那个项目备注是需要用户去填写的,当他点击后就会出现虚拟键盘,但安卓手机弹出键盘会遮住这个输入框,以至于用户看不见了。苹果手机天然不会喔,苹果手机的键盘弹出来是占了下面的位置,从而把页面推了上去,整个页面就缩小了就不会出现这样的情况。安卓手机情况如下图:
我不停尝试去解决这个问题,但最终都不成功。
思考一:
如果能模仿苹果一样,当键盘弹出来的时候,将整个页面缩小成页面底部刚好贴着键盘,那就完美了。但是这个想法最大的问题就是,不能准确拿到虚拟键盘的高度(后来测试时发现,虚拟键盘原来还可以改变大小……所以这个高度更不可能拿到了……),但即使拿到高度,能完成当备注那个textarea onfocus时,键盘弹出并准确计算成整个页面缩小成页面底部刚好贴着键盘这个效果,还有一个最终大坑!就是没有办法监听到虚拟键盘什么时候被用户收起来!这样一来就不知道什么时候去还原这个页面了……虽然onblur事件可以在失去焦点时去还原这个页面,但安卓用户的习惯操作应该是按手机上的物理返回键或者虚拟键盘上的那个收起键盘的按钮,问题是无论返回还是收起键盘,焦点还是在那里,没有失去呀,这就没办法了……所以最终的问题关键是,怎样监听到虚拟键盘……
思考二:
尝试了一个方法效果已经很接近了。代码如下:
<div id="fix-hegiht" style="height: 300px; width: 100%; display: none;"></div>
其实就是在文本框onfocus时,把上面这个空白高度的div显示出来,于是就能把页面撑高,就会出现滚动条,效果挺好如下图:
而且收键盘后,竟然页面会回到顶部(我怀疑触发了resize事件,但经测试,无论键盘弹出收起都没触发哎,遗憾),这不就是想要的效果了吗!如下图:
会发现虽然回到了顶部,看起来好像跟一开始没有滚动条的样子一样,但现在用户是可以滚动的,因为那个负责撑高的空div仍然在那里,如果用户滚下去就会看到一大片空白,这肯定是要处理掉的。于是问题又到了“什么时候去删了这个空div”?最好的当然是能监听到键盘什么时候被收起来啦,但这个似乎不太可能。于是我想,能不能当滚动条滚动到空div的地方就把它删了。确实可以这样子,但体验不好啊,突然就闪了一下,而且,如果当用户弹出键盘时去操作可以滚动的页面,滚到空div的地方就删了这个div,那瞬间输入框又被盖住了……
我还想,能不能滚动条滚到空div的地方,就不能往下滚了呢?如果这样,用户滚不下去,那留着这个空白div也没问题啊。但是这个想法却实现不了,搞来搞去没办法搞出来。
思路三:
我就想这个虚拟键盘挡住输入框的问题应该到处可见啊,各种注册页面估计都有,那怎么会这么多年来都用安卓的我竟然没觉得这是个问题!?于是我跑去随便找一个注册页面(如搜狐邮箱)http://wap.mail.sohu.com/,截图如下:
竟然可以!?整个页面往上挪了一点,但没出现滚动条!!这究竟是怎么做到的!!??我就奇怪是不是浏览器问题,因为这个是手机自带的浏览器访问的。于是我开微信,然后点开这个网站,果然如下图:
原来是微信的浏览器就会这样子……最后跑去QQ浏览器那里看,也有人问这个问题,估计是X5内核升级之后的BUG……最后为了能使用,还是将就使用空白div撑高的方法。在寻找解决方法的过程中,还发现有段很漂亮的代码。来自http://efe.baidu.com/blog/mobile-fixed-layout/ 也许以后会用上,可以用来判断滚动条是否到某个位置,还有滑动的方向,以此来判断什么时候阻止滚动条滚动。代码已经过详细注释:
<script type="text/javascript">
// 防止内容区域滚到底后引起页面整体的滚动
var content = document.querySelector('main');
var startY;
content.addEventListener('touchstart', function (e) {
//起始位置
startY = e.touches[0].clientY;
});
content.addEventListener('touchmove', function (e) {
// 高位表示向上滚动
// 底位表示向下滚动
// 1容许 0禁止
var status = '11';
var ele = this;
//当前位置
var currentY = e.touches[0].clientY;
//如果垂直偏移量scrollTop为0,说明要么内容小于容器没有滚动条,要么大于容器但滚动条在顶部
if (ele.scrollTop === 0) {
// 如果内容小于容器则同时禁止上下滚动,若大于则可以向下滚动
status = ele.offsetHeight >= ele.scrollHeight ? '00' : '01';
} else if (ele.scrollTop + ele.offsetHeight >= ele.scrollHeight) {
/*
1.垂直偏移量scrollTop+整个元素的尺寸offsetHeight(包括边框)=整个内容区域scrollHeight
证明已经滚到底部了只能向上滚动;
2.其中offsetHeight(包括边框)是否要换成clientHeight(不包括边框)?
*/
status = '10';
}
//若status==11则上面三种情况都不是,这种情况是有滚动条且滚动条不在顶部也不在底部
if (status != '11') {
// 判断当前的滚动方向
var direction = currentY - startY > 0 ? '10' : '01';
/*
1.操作方向和当前允许状态求与运算,运算结果为0,就说明不允许该方向滚动,则禁止默认事件,阻止滚动
2.status为00,说明没有滚动条,此时无论direction是上还是下,都要阻止滚动
3.status为01,说明有滚动条,可以向下滚动,此时direction为01则符合向下滚动
4.status为10,说明有滚动条,可以向上滚动,此时direction为10则符合向上滚动
5.综上a.没有滚动条 b.滚动条在顶部但还向上滚动 c.滚动条在底部但还向下滚动 都要阻止滚动
*/
if (!(parseInt(status, 2) & parseInt(direction, 2))) {
stopEvent(e);
}
}
});
</script>
这里用到了HTML5的touch事件,分别touch事件有四个:touchstart、touchmove、touchend、touchcancel。当你滑动屏幕的时候,他们的触发顺序是:
touchstart:当手指接触屏幕时触发
touchmove:当已经接触屏幕的手指开始移动后触发
touchend:当手指离开屏幕时触发
touchcancel:当某种touch事件非正常结束时触发
所以可以通过上图这些属性去获取touch时的位置。
以上内容给大家介绍了安卓输入框被虚拟键盘挡住的问题(微信开发),希望对大家有所帮助!
猜你喜欢
- 前言本文主要介绍的是关于C#中LINQ多条件JOIN时为什么可以使用匿名类的相关内容,分享出来供大家参考学习,下面话不多说了,来一起看看详细
- Java以命令模式设计模式1、简单介绍意图:将一个请求封装成一个对象,从而使您可以用不同的请求对客户进行参数化。主要解决:在软件系统中,行为
- Android ViewPager2 UsageViewPager2 是 ViewPager 的升级版本,解决了 ViewPager 的大部
- Java中字符串对象创建有两种形式,一种为字面量形式,如String str = "droid";,另一种就是使用new
- 现在的手游基本都是重复操作,一个动作要等好久,结束之后继续另一个动作.很麻烦,所以动起了自己写一个游戏辅助的心思.这个辅助本身没什么难度,就
- 关于Android实现文字上下滚动这个功能,我目前有两种方法实现: 一个是在TextView 中加上翻转的动画效果,然后设置循环滚动;一种是
- 本文实例为大家分享了java swing实现简单计算器界面的具体代码,供大家参考,具体内容如下已经学习了一部分的swing知识,现在综合运用
- 有时候我们在使用java编程的时候,想启动线程,怎么启动呢,下面来分享一下方法第一步在我们的电脑上打开eclipse,创建一个java项目,
- package com.java.db;import java.lang.reflect.Constructor;import java.l
- 最近做一个需求,需求中的bean只用于生成一次json使用,所以想通过配置来动态的生成,查了一下,java还真有这个实现。java动态的生成
- 今天是开篇,得要吹一下算法,算法就好比程序开发中的利剑,所到之处,刀起头落。 针对现实中的排序问题,算法有七把利剑可以助你马道成功
- 介绍在 .NET4.0 之前,如果我们需要在多线程环境下使用 Dictionary 类,除了自己实现线程同步来保证线程安全外,我们没有其他选
- 问题描述在应用MyBatis时,使用对象关系映射,将对象和Aliase映射起来。在Mybatis的文档明确写出,如果你没有明确定义实体类的A
- 本文实例讲述了Java Arrays工具类用法。分享给大家供大家参考,具体如下:Arrays类功能描述Arrays类是一个工具类,其中包含了
- 介绍我们都知道函数是程序中的基本模块,代码段。那高阶函数呢?听起来很好理解吧,就是函数的高阶(级)版本。它怎么高阶了呢?我们来看下它的基本定
- 在日常工作中,我们可能常常需要打印各种文件资料,比如word文档。对于编程员,应用程序中文档的打印是一项非常重要的功能,也一直是一个非常复杂
- Map的存储结构式Key/Value形式,Key 和 Value可以是普通类型,也可以是自己写的JavaBean(本文),还可以是带有泛型的
- 实现HandlerInterceptor接口或者继承HandlerInterceptor的子类,比如Spring 已经提供的实现了Handl
- 像ipconfig /all 这样的CMD命令想必大家都知道,但是很多童鞋可能不知道怎么写这样的控制台带参数的程序,其实很简单,我们先看建立
- 前言Spark Sql可以通过UDF来对DataFrame的Column进行自定义操作。在特定场景下定义UDF可能需要用到Spark Con