PS:以下通过开发时遇到的问题来具体介绍。
背景如下:安卓电视红外触屏框不能响应onClick事件,触屏框底层驱动不支持onclick事件。
以下通过对项目从分析到解决问题过程作一个简单的介绍:
以下通过java层模拟Click的DOWN/UP事件作为解决思路进行扩展。
对于问题(DOWN意为 OnTouch中的事件,“Click”表状态,依此类推)
// 注册触碰事件监听器
floatImage.setOnTouchListener(new OnTouchListener() {
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
不断判断按住时间是否大于额定值,如果是悬浮球可被移动
break;
case MotionEvent.ACTION_MOVE:
if (移动大于灵敏度) {
焦点是移动状态
}
if (可被移动) {
悬浮球移动
}
break;
case MotionEvent.ACTION_UP:
if (焦点判断未移动 && 悬浮球不能移动) {
//Click
}
break;
}
}
});
具体实现Demo如下(代码是刚工作不久写的,有很多瑕疵- -):
floatImage.setOnTouchListener(new OnTouchListener() {
int firstx = 0;
int firsty = 0;
Thread touchthThread = null;
private long firsttime;
private long secondtime;
boolean ifmoveable;
boolean ismousemove;
boolean ifstopthread;
public boolean onTouch(View v, MotionEvent event) {
x = event.getRawX();
y = event.getRawY();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
firsttime = System.currentTimeMillis();
// Log.i("TopFloatService", "ACTION_DOWN");
ifstopthread = false;
ismousemove = false;
ismoving = false;
ifmoveable = false;
touchthThread = new Thread(new Runnable() {//这里可以使用线程池,是个优化点
public void run() {
while (!ismoving) {
if (ifstopthread)
break;
secondtime = System.currentTimeMillis();
if (secondtime - firsttime >= 600
&& !ismousemove) {
mHandler.sendEmptyMessage(START_ANIMATION);//启动抖动动画,表示长按事件,悬浮球可被移动!
ifmoveable = true;
break;
}
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
});
touchthThread.start();
firstx = ballWmParams.x;
firsty = ballWmParams.y;
mTouchStartX = (int) event.getX();
mTouchStartY = (int) event.getY();
break;
case MotionEvent.ACTION_MOVE:
// Log.i("TopFloatService", "ACTION_MOVE");
int nowx = (x - mTouchStartX) >= (float) 0.00 ? (int) (x - mTouchStartX)
: 0;
int nowy = (y - mTouchStartY) >= (float) 0.00 ? (int) (y - mTouchStartY)
: 0;
if (Math.sqrt((nowx - firstx) * (nowx - firstx)
+ (nowy - firsty) * (nowy - firsty)) >= sensitivity) {
ismousemove = true;
}
// Log.i("TopFloatService ismousemove:nowx - firstx,nowy - firsty",
// ismousemove+","+(nowx - firstx)+","+(nowy - firsty));
if (ifmoveable) {
ismoving = true;
updateViewPosition();
if (touchthThread != null && !touchthThread.isAlive())
touchthThread = null;
}
// Log.i("TopFloatService ifmoveable:", ifmoveable+"");
break;
case MotionEvent.ACTION_UP:
// Log.i("TopFloatService", "ACTION_UP");
ifstopthread = true;
// Log.i("TopFloatService ifmoveable:,ismousemove:",
// ifmoveable+","+ismousemove);
if (!ifmoveable && !ismousemove) {
int mx;
int my;
if ((int) ballWmParams.y
+ ballView.getLayoutParams().height
+ layout_mainLayout.getLayoutParams().height < screenheight) {
my = (int) ballWmParams.y
+ ballView.getLayoutParams().height;
} else {
my = screenheight
- layout_mainLayout.getLayoutParams().height
- 5;
}
if ((int) ballWmParams.x
+ ballView.getLayoutParams().width
+ layout_mainLayout.getLayoutParams().width < screenwidth) {
mx = (int) ballWmParams.x
+ ballView.getLayoutParams().width;
} else {
mx = screenwidth
- layout_mainLayout.getLayoutParams().width
- 5;
}
RelativeLayout.LayoutParams layoutParams = (LayoutParams) layout_mainLayout
.getLayoutParams();
layoutParams.setMargins(
mx,
my,
screenwidth
- mx
+ layout_mainLayout.getLayoutParams().width,
screenheight
- my
+ layout_mainLayout.getLayoutParams().height);
layout_mainLayout.setLayoutParams(layoutParams);
pop = new PopupWindow(menuView, screenwidth,
screenheight);
pop.showAtLocation(ballView, Gravity.NO_GRAVITY, mx, my);
pop.update();
floatImage.setVisibility(View.INVISIBLE);
}
mTouchStartX = mTouchStartY = 0;
if (touchthThread != null && !touchthThread.isAlive())
touchthThread = null;
break;
}
// 如果拖动则返回false,否则返回true
if (ifmoveable && ismousemove) {
return false;
} else {
return true;
}
}
});