利用LayoutParams.y设置组件跟随手指滑动时遇到的问题
2016-04-18 12:46
561 查看
今天写代码时遇到一个问题,即使用WindowManger添加了一个组件之后,通过设置OnTouchListener来给组件添加跟随手指移动的事件。代码如下:
实际使用中很快遇到了问题,就是在我滑动组件的一刹那,组件会有一次位置的突变。
经过分析,layoutParams.x和layoutParams.y设置的是组件左上角的坐标,而getRawX、getRawY是到屏幕左上角到手指点击位置的距离,即中间多了一段event.getX和event.getY。好吧,修改后的代码如下:
实际使用中发现,X轴不突变了,Y轴还在突变,这是因为什么?
经过分析,发现问题出现在这里:
假如我们利用layoutParams将组件高度设置为0时,可以看到此时组件是处于通知栏下的。但是触摸顶端时,组件的event.getRawY不为0,为通知栏高度。
上述代码中我们用layoutParams.y设置组件的高度时,组件在屏幕的实际高度为 y + 通知栏 高度。我们通过getRawY-getY获取移动的高度是包含了通知栏的。但是由于我们是通过layoutParams.y设置组件高度的,而layoutParams.y是不需要通知栏高度的。所以getRawY-getY的结果还要减去通知栏高度才能正确移动。
归结到底,还是因为layoutParams.y不包括通知栏高度,而getRawY是纯粹的屏幕计算,所以包括通知栏高度。
知道了原因,修改后的代码如下:
其中获取通知栏高度的代码如下:
b.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { int rawX = (int) event.getRawX(); int rawY = (int) event.getRawY(); switch (event.getAction()) { case MotionEvent.ACTION_MOVE: layoutParams.x = rawX; layoutParams.y = rawY; manager.updateViewLayout(b, layoutParams); break; default: break; } return false; } });
实际使用中很快遇到了问题,就是在我滑动组件的一刹那,组件会有一次位置的突变。
经过分析,layoutParams.x和layoutParams.y设置的是组件左上角的坐标,而getRawX、getRawY是到屏幕左上角到手指点击位置的距离,即中间多了一段event.getX和event.getY。好吧,修改后的代码如下:
b.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { int rawX = (int) event.getRawX(); int rawY = (int) event.getRawY(); int disX = rawX - downX; int disY = rawY - downY; switch (event.getAction()) { case MotionEvent.ACTION_DOWN: downX = (int) event.getX(); downY = (int) event.getY(); break; case MotionEvent.ACTION_MOVE: layoutParams.x = disX; //75是我手机消息栏的高度,好吧,消息栏高度的获取方法 layoutParams.y = disY; manager.updateViewLayout(b, layoutParams); break; default: break; } return false; } });
实际使用中发现,X轴不突变了,Y轴还在突变,这是因为什么?
经过分析,发现问题出现在这里:
假如我们利用layoutParams将组件高度设置为0时,可以看到此时组件是处于通知栏下的。但是触摸顶端时,组件的event.getRawY不为0,为通知栏高度。
上述代码中我们用layoutParams.y设置组件的高度时,组件在屏幕的实际高度为 y + 通知栏 高度。我们通过getRawY-getY获取移动的高度是包含了通知栏的。但是由于我们是通过layoutParams.y设置组件高度的,而layoutParams.y是不需要通知栏高度的。所以getRawY-getY的结果还要减去通知栏高度才能正确移动。
归结到底,还是因为layoutParams.y不包括通知栏高度,而getRawY是纯粹的屏幕计算,所以包括通知栏高度。
知道了原因,修改后的代码如下:
b.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { int rawX = (int) event.getRawX(); int rawY = (int) event.getRawY(); int disX = rawX - downX; int disY = rawY - downY; switch (event.getAction()) { case MotionEvent.ACTION_DOWN: downX = (int) event.getX(); downY = (int) event.getY(); break; case MotionEvent.ACTION_MOVE: layoutParams.x = disX; //75是我手机消息栏的高度,好吧,通知栏高度的获取方法 layoutParams.y = disY - statusBarHeight; manager.updateViewLayout(b, layoutParams); break; default: break; } return false; } });
其中获取通知栏高度的代码如下:
public static int getStatusBarHeight(Context context) { Class<?> c = null; Object obj = null; Field field = null; int x = 0, statusBarHeight = 0; try { c = Class.forName("com.android.internal.R$dimen"); obj = c.newInstance(); field = c.getField("status_bar_height"); x = Integer.parseInt(field.get(obj).toString()); statusBarHeight = context.getResources().getDimensionPixelSize(x); } catch (Exception e1) { e1.printStackTrace(); } return statusBarHeight; }
相关文章推荐
- 关于PHP的!
- 关于PHP的urldecode与null
- 一致性哈希算法简单分析及php实现
- Thinkphp 事物问题
- matplotlib绘图基础
- 使用EditPlus和批处理删除文本重复内容行
- PHP语言 -- 投票练习题
- Laravel5 集合Collection
- 系统吞吐量(TPS)、用户并发量、性能测试概念和公式
- PHP实现快速排序
- php 获取提交来源,判断从哪里提交的
- PHP下利用PHPMailer配合QQ邮箱下的域名邮箱发送邮件
- php ++和逻辑运算的细节
- 每天laravel-20160718|Command-2
- 每天laravel-20160718|Command-2
- Yii框架分库设计
- php语句中的(array)的含义
- php-fpm 启动参数及重要配置详解
- PHP获取一天起始时间戳,结束时间戳
- 批量检查代理ip是否可用 curl-multi php检测ip代理是否有效