Android 如何将触摸坐标绑定到图像
我正在开发一个指南针类型的Android应用程序,在这个应用程序中,我会有一个指南针的图像,用字母表示不同的方向(“N”表示北方,“E”表示东方等等)。用户可以按任意字母,获取有关给定方向的信息。我正在寻找一种将触摸坐标绑定到图像的方法,也就是说,如果用户按下字母“N”,他们总是会得到与手机所面对的方向无关的类似坐标。下面是我现在使用的代码Android 如何将触摸坐标绑定到图像,android,Android,我正在开发一个指南针类型的Android应用程序,在这个应用程序中,我会有一个指南针的图像,用字母表示不同的方向(“N”表示北方,“E”表示东方等等)。用户可以按任意字母,获取有关给定方向的信息。我正在寻找一种将触摸坐标绑定到图像的方法,也就是说,如果用户按下字母“N”,他们总是会得到与手机所面对的方向无关的类似坐标。下面是我现在使用的代码 @Override public View onCreateView(LayoutInflater inflater,
@Override
public View onCreateView(LayoutInflater inflater,
ViewGroup container,
Bundle savedInstanceState) {
View v=inflater.inflate(R.layout.compass_fragment, container, false);
compassView = (CompassView) v.findViewById(R.id.compass_view);
compassView.setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View view, MotionEvent motion) {
Log.i(TAG, "In onTouch");
// Get the action that was done on this touch event
switch (motion.getAction())
{
case MotionEvent.ACTION_DOWN:
{
return true;
}
case MotionEvent.ACTION_UP:
{
float x = motion.getX();
float y = motion.getY();
Log.i(TAG, "ACTION UP x = " + x + " y = " + y);
break;
}
}
// if you return false, these actions will not be recorded
return true;
}
});
mSensorManager = (SensorManager)getActivity().getSystemService(Context.SENSOR_SERVICE);
accelerometer = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
magnetometer = mSensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);
return(v);
}
我算出了我问题的答案。它按照我想要的方式工作,不使用按钮。我附上下面的代码,希望它可能对其他人有用 为了获得指南针上的触摸方向,我计算当前指南针方位(度变量,由另一类调用的setDegrees方法更新)和触摸位置相对于Y轴的角度之间的偏移角
public class CompassView extends ImageView {
private float degrees=0;
private String touchDirection;
public CompassView(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
protected void onDraw(Canvas canvas) {
int height = this.getHeight();
int width = this.getWidth();
canvas.rotate(360-degrees, width/2, height/2);
super.onDraw(canvas);
}
public void setDegrees(float degrees) {
this.degrees = degrees;
this.invalidate();
}
@Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
return true;
case MotionEvent.ACTION_MOVE:
break;
case MotionEvent.ACTION_UP:
float eventX = event.getX();
float eventY = event.getY();
touchDirection = getTouchDirection(eventX, eventY);
Context context = getContext();
Intent intent = new Intent(context, CompassDirectionInfo.class);
Bundle bundle = new Bundle();
bundle.putString("DIRECTION", touchDirection);
intent.putExtras(bundle);
context.startActivity(intent);
break;
default:
return false;
}
return true;
}
private String getTouchDirection (float eventX, float eventY) {
String direction = "";
float centreX = getWidth()/2, centreY = getHeight()/2;
float tx = (float) (eventX - centreX), ty = (float) (eventY - centreY);
float radius = (float) Math.sqrt(tx*tx + ty*ty);
float offsetX = 0, offsetY = radius, adjEventX = eventX - centreX, adjEventY = centreY - eventY;
double cosaU = ((offsetX * adjEventX) + (offsetY * adjEventY));
double cosaD = ( Math.sqrt((offsetX * offsetX) + (offsetY * offsetY)) * Math.sqrt((adjEventX * adjEventX) + (adjEventY * adjEventY)));
double cosa = cosaU / cosaD;
double degr = ( Math.acos(cosa) * (180 / Math.PI));
if (adjEventX < 0)
degr = 360 - degr;
float offsetDegrees = (float) (degrees + degr);
if (offsetDegrees > 360)
offsetDegrees = offsetDegrees - 360;
if (offsetDegrees < 22.5 || offsetDegrees > 336.5)
direction = "NORTH";
else if (offsetDegrees > 22.5 && offsetDegrees < 67.5)
direction = "NORTHEAST";
else if (offsetDegrees > 67.5 && offsetDegrees < 112.5)
direction = "EAST";
else if (offsetDegrees > 112.5 && offsetDegrees < 156.5)
direction = "SOUTHEAST";
else if (offsetDegrees > 156.5 && offsetDegrees < 201.5)
direction = "SOUTH";
else if (offsetDegrees > 201.5 && offsetDegrees < 246.5)
direction = "SOUTHWEST";
else if (offsetDegrees > 246.5 && offsetDegrees < 291.5)
direction = "WEST";
else if (offsetDegrees > 291.5 && offsetDegrees < 336.5)
direction = "NORTHWEST";
return direction;
}
}
公共类CompassView扩展了ImageView{
私有浮动度=0;
私有字符串方向;
公共CompassView(上下文、属性集属性){
超级(上下文,attrs);
}
@凌驾
受保护的void onDraw(画布){
int height=this.getHeight();
int width=this.getWidth();
画布。旋转(360度,宽度/2,高度/2);
super.onDraw(帆布);
}
公共空间设置度(浮动度){
这个。度=度;
这个。使无效();
}
@凌驾
公共布尔onTouchEvent(运动事件){
开关(event.getAction()){
case MotionEvent.ACTION\u DOWN:
返回true;
case MotionEvent.ACTION\u移动:
打破
case MotionEvent.ACTION\u UP:
float eventX=event.getX();
float eventY=event.getY();
touchDirection=getTouchDirection(eventX,eventY);
Context=getContext();
意向意向=新意向(上下文、CompassDirectionInfo.class);
Bundle=新Bundle();
bundle.putString(“方向”,触摸方向);
意向。额外支出(捆绑);
背景。开始触觉(意图);
打破
违约:
返回false;
}
返回true;
}
私有字符串getTouchDirection(float-eventX,float-eventY){
字符串方向=”;
float-centreX=getWidth()/2,centreY=getHeight()/2;
浮动tx=(浮动)(eventX-centreX),ty=(浮动)(eventY-centreY);
浮动半径=(浮动)数学sqrt(tx*tx+ty*ty);
float offsetX=0,offsetY=radius,adjEventX=eventX-centreX,adjEventY=centreY-eventY;
双cosaU=((offsetX*adjventx)+(offsetY*adjventy));
double-cosaD=(Math.sqrt((offsetX*offsetX)+(offsetY*offsetY))*Math.sqrt((adjEventX*adjEventX)+(adjEventY*adjEventY));
双cosa=cosaU/cosaD;
双精度=(数学acos(cosa)*(180/数学PI));
如果(adjEventX<0)
degr=360-degr;
浮动偏移度=(浮动)(度+除气);
如果(偏移度>360)
偏移度=偏移度-360;
如果(偏移度<22.5 | |偏移度>336.5)
方向=“北”;
否则如果(偏移度>22.5和偏移度<67.5)
方向=“东北”;
否则如果(偏移度>67.5和偏移度<112.5)
方向=“东”;
否则如果(偏移度>112.5和偏移度<156.5)
方向=“东南”;
否则如果(偏移度>156.5和偏移度<201.5)
方向=“南”;
否则如果(偏移度>201.5和偏移度<246.5)
方向=“西南”;
否则如果(偏移度>246.5和偏移度<291.5)
方向=“西”;
否则如果(偏移度>291.5和偏移度<336.5)
方向=“西北”;
返回方向;
}
}
所以你知道如何旋转图像,却不知道如何用触摸将其绑定?吉娜,不,我不知道,否则我不会问这个问题。我刚接触安卓系统,仍在学习它是如何协同工作的。看来你很清楚该怎么做,如果你能给我一些建议,我将不胜感激。谢谢。然后了解如何旋转图像。对于“N”或“E”,将其设置为类似于Button/ImageButton的对象,这样您就不需要知道坐标。是的,我正在考虑使用Button/ImageButton,但我想知道是否存在类似于iOS中的“locationInView”的内容,它返回视图的本地坐标系中触摸的坐标(手势识别器已连接到其上)。