前段时间在做一个android设备控制android设备的程序,写了一个获取坐标的点,由于使用太多的if else判断条件,虽然能实现获取x,y的功能,自己写的自己看着就已经头晕了,于是今天花了点时间,整理了一下。我实现的场景是,当我的手机被投射到另一个android设备上,通过surfaceview显示手机屏幕(视频流),我不知道手机是竖屏还是横屏,如果在显示端坐处理,只能比较图片,看那边有黑边。显示效果可能有三种,如下:
在这种情况先获取显示视频流surfaceview的x,y需要计算转换发送到手机端,这样操作才是同一个点。
下面通过一个例子来了解计算过程,可以通过两个Imageview来模拟远程显示设备和本地设备,在远程显示的Imageview上点击,通过Ontouch方法拿到x,y值,通过计算在本地Imageview上画出点,看远程点击位置是不是跟本地换算出来的位置点能一一对应上,我的手机在开发者选项中开启了指针轨迹,在远程Imageview上操作的轨迹会被记录下来,在本地Imageview上具体点会点出红点,看实例图,如下:
具体实现代码:
package com.example.darren.surfacepro;
import android.content.Context;
import android.view.WindowManager;
/**
* Created by darren.qi on 2013/4/22.
*/
public class LogicReckon {
private int mRemoteDeviceWidth = 700;
private int mRemoteDeviceHeight = 650;
private int mLocalDeviceWidth;
private int mLocalDeviceHeight;
private int mOrientation=1;
private Context mContext=null;
public LogicReckon(Context context) {
mContext=context;
}
public void setOrientation(int val)
{
WindowManager wm = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
mLocalDeviceWidth = 700;
mLocalDeviceHeight = 350;
mOrientation=val;
}
public PointDevice convert(float x,float y)
{
PointDevice point=new PointDevice();
double scaling=(mLocalDeviceHeight*(1.0d)/mLocalDeviceWidth);
double scalingHeight=mLocalDeviceHeight*(1.0d)/mRemoteDeviceHeight;
double scalingWidth=mLocalDeviceWidth*(1.0d)/mRemoteDeviceWidth;
double height= (scaling*mRemoteDeviceWidth);
double width= (mRemoteDeviceHeight/scaling);
double realheight=0;
double realwidth=0;
double Ay=0;
double Ax=0;
//取远程设备的宽做基准
if(height<=mRemoteDeviceHeight)
{
realwidth=mRemoteDeviceWidth;
realheight=height;
Ay=(mRemoteDeviceHeight-height)/2;
if((y-Ay)<0||(y-Ay)>realheight)
return null;
scalingHeight=mLocalDeviceHeight*(1.0d)/realheight;
point.setX((float) (x * scalingWidth)).setY((float) ((y-Ay)*scalingHeight));
}
//取远程设备的高为做基准
else if(width<=mRemoteDeviceWidth)
{
realwidth=width;
realheight=mRemoteDeviceHeight;
Ax=(mRemoteDeviceWidth-width)/2;
if((x-Ax)<0||(x-Ax)>realwidth)
return null;
scalingWidth=mLocalDeviceWidth*(1.0d)/realwidth;
point.setX((float) ((x-Ax) * scalingWidth)).setY((float) (y * scalingHeight));
}
return point;
}
public class PointDevice{
private float x;
private float y;
public float getX() {
return x;
}
public PointDevice setX(float x) {
this.x = x;
return this;
}
public float getY() {
return y;
}
public PointDevice setY(float y) {
this.y = y;
return this;
}
}
}
这段代码放置到手机端,当手机端通过连接方式usb或者tcp获得到显示设备端的x,y值,通过onConfigurationChanged判断横竖屏后获得宽高度,转换得到真正的x,y位置,模拟input实时motion事件出来,手机就会还原显示端在surfaceview上的操作。
当一张图片在imageview上放大缩小或者移动后,想获取在屏幕上点击后,真正的图片上的位置点,类似,显示一张图片,当点击某个位置后,在点击位置上绘制图片或者做标记之类的。这种情况可以使用Imageview上移动缩放的矩阵来获取真正相对于图片的左上角的位置点。可以通过一行代码计算出相对点,等以后有时间了在整理一下之前代码,也贴出来吧。
[测试demo下载]