仇九 2023-01-12 20:26 采纳率: 100%
浏览 47
已结题

webview打包html本地网页时在手机边缘处的触屏问题

我在使用Android Studio将一个html文件打包成一个apk,使用webview运行。
因为是要做一个简单的小游戏,所以需要用到触屏的操控,于是我使用了事件touchstart,touchend,touchmove来获取玩家点击的相关信息。
但在屏幕边缘处,事件touchend的触发有明显的问题。

正常来说,正常人在手机屏幕上进行一次快速的点击,touchstart和touchend的触发间隔相差50到100ms左右。
我使用touchend中event对象的时间戳减去touchstart的中event对象的时间戳,验证了这个结论,我点击一次手机屏幕后这两个时间戳的差值是60到80ms,这是正常的。

但当我点击屏幕的边缘处时,这两个时间戳的差值是0到3ms,这很明显不对,如果touchstart是正常触发的,那么touchend触发就过早了。
即使我触摸后瞬间抬起,或者触摸后突然将手指略微移动到可触摸范围外(touchmove也没触发),那也不可能这么短,肯定是有什么问题。
这是示例图:
其中灰色和红色部分合起来是游戏的显示区域,蓝色部分是前置摄像头,红色部分就是点击时touchend触发就过早的边缘处。
红色部分分为三部分,一是最上面和最下面的一定像素内,这一部分和手机是曲面屏无关,且当我触摸的时候,既然能触发touchstart,那么当我手指还没有抬起的时候不应该
触发touchend才对。而右方的红色部分似乎就是导航键所在的区域,但程序在运行时导航键已被隐藏,不应该是导航键的问题。

img

这是我测试时使用的简单html文件:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0;"/>
    </head>
    <body style="background-color: black">
        <canvas width="800" height="600" id="test"> </canvas>
        <script type="text/javascript">

var canvasForTest = document.getElementById('test');
var contextForTest = canvasForTest.getContext('2d')
var touchstartTimestamp = 0;

window.addEventListener('touchstart', (e)=>{
    touchstartTimestamp = e.timeStamp;
    console.log("start");
});

window.addEventListener('touchend', (e)=>{
    contextForTest.clearRect(0,0,800,600);
    contextForTest.fillStyle = "#ffffff";
    contextForTest.font="48px Georgia";
    let text = "时间间隔为"+Math.floor(e.timeStamp-touchstartTimestamp)+"ms"
    let width = contextForTest.measureText(text).width;
    contextForTest.fillText(text,(800-width)/2,(600-48*96/72)/2,800);
    console.log("end",e.timeStamp-touchstartTimestamp);
});

window.addEventListener('touchmove', (e)=>{
    console.log("move");
});

window.addEventListener('touchcancel', (e)=>{
    console.log("cancel");
});


        </script>
    </body>
</html>

测试的手机型号有:
vivio的X50,honor的magic 3 pro。

我在网上查找答案,使用了许多办法,包括什么event.preventDefault()和event.stopPropagation()但都无关且无效,很可能也不是页面滚动(scroll)的问题。
我在想是不是Android Studio中java语句的问题,但我想尽量能在html文件中通过某些语句解决问题,或者能找到这个问题发生的原因。

  • 写回答

2条回答 默认 最新

  • heart_6662 2023-01-12 20:39
    关注

    很明显,在边缘处触发的 touchstart 和 touchend 事件有可能是被系统所拦截的。在 Android 中,系统会在屏幕的边缘区域设置一个边界,如果用户在这个边界区域触摸屏幕,系统会拦截这个事件并执行一些系统功能,如弹出菜单,滑动等。这就导致了 touchstart 和 touchend 事件在边缘处触发的问题。

    解决方法有很多,你可以在程序中禁用系统的边界拦截功能,或者在设计 UI 的时候避免在屏幕边缘设置可点击的元素。另外你也可以在程序中对边界处的事件进行特殊的处理,以确保程序的正常运行。

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论 编辑记录
查看更多回答(1条)

报告相同问题?

问题事件

  • 系统已结题 1月21日
  • 已采纳回答 1月13日
  • 修改了问题 1月12日
  • 创建了问题 1月12日

悬赏问题

  • ¥20 机器学习能否像多层线性模型一样处理嵌套数据
  • ¥20 西门子S7-Graph,S7-300,梯形图
  • ¥50 用易语言http 访问不了网页
  • ¥50 safari浏览器fetch提交数据后数据丢失问题
  • ¥15 matlab不知道怎么改,求解答!!
  • ¥15 永磁直线电机的电流环pi调不出来
  • ¥15 用stata实现聚类的代码
  • ¥15 请问paddlehub能支持移动端开发吗?在Android studio上该如何部署?
  • ¥20 docker里部署springboot项目,访问不到扬声器
  • ¥15 netty整合springboot之后自动重连失效