Android 如何将触摸坐标绑定到图像

Android 如何将触摸坐标绑定到图像,android,Android,我正在开发一个指南针类型的Android应用程序,在这个应用程序中,我会有一个指南针的图像,用字母表示不同的方向(“N”表示北方,“E”表示东方等等)。用户可以按任意字母,获取有关给定方向的信息。我正在寻找一种将触摸坐标绑定到图像的方法,也就是说,如果用户按下字母“N”,他们总是会得到与手机所面对的方向无关的类似坐标。下面是我现在使用的代码 @Override public View onCreateView(LayoutInflater inflater,

我正在开发一个指南针类型的Android应用程序,在这个应用程序中,我会有一个指南针的图像,用字母表示不同的方向(“N”表示北方,“E”表示东方等等)。用户可以按任意字母,获取有关给定方向的信息。我正在寻找一种将触摸坐标绑定到图像的方法,也就是说,如果用户按下字母“N”,他们总是会得到与手机所面对的方向无关的类似坐标。下面是我现在使用的代码

@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”的内容,它返回视图的本地坐标系中触摸的坐标(手势识别器已连接到其上)。