-1

我正在开发一个 Compass 类型的 Android 应用程序,其中我会有一个 Compass 的图像,其中的字母表示不同的方向(“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);
  }
4

1 回答 1

0

我想出了我的问题的答案。它以我想要的方式工作,无需使用按钮。我附在代码下面,希望它对其他人有用。

为了获得指南针上的触摸方向,我计算了当前指南针方位(由另一个类调用的 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;
    }
}
于 2013-09-05T01:55:54.887 回答