Mega Code Archive

 
Categories / Android / UI
 

Compass View

//package apps.compass; import java.util.List; import android.app.Activity; import android.content.Context; import android.hardware.Sensor; import android.hardware.SensorEvent; import android.hardware.SensorEventListener; import android.hardware.SensorManager; import android.os.Bundle; import android.content.Context; import android.content.res.Resources; import android.graphics.Canvas; import android.graphics.drawable.Drawable; import android.util.Log; import android.view.MotionEvent; import android.view.View; public class CompassView extends View {   private float mGraduationRotateAngle = 0;   private float mPointerRotateAngle = 0;          private Drawable mGraduationDrawable = null;     private Drawable mPointerDrawable = null;          private float mGraduationDrawableRadius = 0;     private float mPointerDrawableRadius = 0;     private float mCanvasCenterX = 0;     private float mCanvasCenterY =0;          private float mPreTouchX = 0;     private float mPreTouchY = 0;   public CompassView(Context context) {     super(context);        Resources res = context.getResources(); //    mGraduationDrawable = res.getDrawable();     mGraduationDrawable.setBounds(0, 0, 300, 300);   //  mPointerDrawable = res.getDrawable();     mPointerDrawable.setBounds(0, 0, 250, 250);          mGraduationDrawableRadius = 300 / 2;     mPointerDrawableRadius = 250 / 2;   }   public void setPointerRotateAngle(float angle) {     if (angle - mPointerRotateAngle > 2 ) {       while (angle - mPointerRotateAngle > 0.2) {         mPointerRotateAngle += 0.2;         this.invalidate();       }     }     else if (angle - mPointerRotateAngle < -2) {       while (mPointerRotateAngle - angle > 0.2) {         mPointerRotateAngle -= 0.2;         this.invalidate();       }       }   }      public void setGraduationRotateAngle(float angle) {     mGraduationRotateAngle = angle;   }      public boolean onTouchEvent(MotionEvent event) {     boolean hasRotation = false;     boolean isClockwise = true;     float dx = event.getX() - mPreTouchX;     float dy = event.getY() - mPreTouchY;          switch (event.getAction()) {     case MotionEvent.ACTION_DOWN:       break;     case MotionEvent.ACTION_MOVE:       if (mPreTouchX > mCanvasCenterX && mPreTouchX < mCanvasCenterX + mGraduationDrawableRadius) {         if (mPreTouchY > mCanvasCenterY && mPreTouchY < mCanvasCenterY + mGraduationDrawableRadius) {           if (dx > 0 && dy < 0) {isClockwise = true; hasRotation = true;}           else if (dx < 0 && dy > 0) {isClockwise = false; hasRotation = true;}           else {hasRotation = false;}         }         else if (mPreTouchY > mCanvasCenterY - mGraduationDrawableRadius && mPreTouchY < mCanvasCenterY){           if (dx > 0 && dy > 0) {isClockwise = false; hasRotation = true;}           else if (dx < 0 && dy < 0) {isClockwise = true; hasRotation = true;}           else {hasRotation = false;}         }       }       else if (mPreTouchX > mCanvasCenterX - mGraduationDrawableRadius && mPreTouchX < mCanvasCenterX){         if (mPreTouchY > mCanvasCenterY && mPreTouchY < mCanvasCenterY + mGraduationDrawableRadius) {           if (dx > 0 && dy > 0) {isClockwise = true; hasRotation = true;}           else if (dx < 0 && dy < 0) {isClockwise = false; hasRotation = true;}           else {hasRotation = false;}         }         else if (mPreTouchY > mCanvasCenterY - mGraduationDrawableRadius && mPreTouchY < mCanvasCenterY) {           if (dx > 0 && dy < 0) {isClockwise = false; hasRotation = true;}           else if (dx < 0 && dy > 0) {isClockwise = true; hasRotation = true;}           else {hasRotation = false;}         }       }       break;     }          if (hasRotation) {       float touchXToCenterX = mPreTouchX - mCanvasCenterX;       float touchYToCenterY = mPreTouchY - mCanvasCenterY;       float touchRadius = (float)Math.sqrt(touchXToCenterX * touchXToCenterX + touchYToCenterY * touchYToCenterY);       float touchPathLen = (float) Math.sqrt(dx * dx + dy * dy);       float rotateDegree = (float) Math.toDegrees(touchPathLen / touchRadius);       Log.d("On Touch", "angle: "+rotateDegree);       if (isClockwise)         this.setGraduationRotateAngle(mGraduationRotateAngle + rotateDegree);       else         this.setGraduationRotateAngle(mGraduationRotateAngle - rotateDegree);       this.invalidate();           }     mPreTouchX = event.getX();     mPreTouchY = event.getY();     return true;   }   protected void onDraw(Canvas canvas) {            int w = canvas.getWidth();     int h = canvas.getHeight();     mCanvasCenterX = w / 2;     mCanvasCenterY = h / 2;         canvas.save();     canvas.translate(mCanvasCenterX, mCanvasCenterY);     canvas.rotate(-mGraduationRotateAngle);     canvas.translate(-mGraduationDrawableRadius, -mGraduationDrawableRadius);     mGraduationDrawable.draw(canvas);     canvas.restore();          canvas.translate(mCanvasCenterX, mCanvasCenterY);     canvas.rotate(-mPointerRotateAngle);     canvas.translate(-mPointerDrawableRadius, -mPointerDrawableRadius);     mPointerDrawable.draw(canvas);   } }  class Compass extends Activity {   private SensorManager mSensorManager = null;   private CompassView mView = null;   private final SensorEventListener mSensorEventListener = new SensorEventListener() {     public void onAccuracyChanged(Sensor sensor, int accuracy) {     }     public void onSensorChanged(SensorEvent event) {       if (mView != null) {         mView.setPointerRotateAngle(event.values[0]);       }     }   };   public void onCreate(Bundle savedInstanceState) {     super.onCreate(savedInstanceState);     mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);      mView = new CompassView(this);      setContentView(mView);   }   public void onResume() {     super.onResume();     List<Sensor> sensorList = mSensorManager         .getSensorList(Sensor.TYPE_ORIENTATION);     if (!sensorList.isEmpty()) {       Sensor sensor = (Sensor) sensorList.get(0);       if (sensor != null)         mSensorManager.registerListener(mSensorEventListener, sensor,             SensorManager.SENSOR_DELAY_GAME);     }   }   public void onStop() {     mSensorManager.unregisterListener(mSensorEventListener);     super.onStop();   } }