Android Open Source - 101AndroidApps Compass View






From Project

Back to project page 101AndroidApps.

License

The source code is released under:

Licenced under the Creative Commons Attribution 4.0 licence. For full text see http://creativecommons.org/licenses/by/4.0/

If you think the Android project 101AndroidApps listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

package com.hulzenga.ioi.android.app_010;
// w ww.  ja va  2s.  c  o  m
import android.content.Context;
import android.graphics.Camera;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Path;
import android.util.AttributeSet;
import android.view.Surface;
import android.view.View;
import android.view.WindowManager;

import java.util.Arrays;

/**
 * Created by jouke on 24-4-14.
 */
class CompassView extends View {


  private static final float COMPASS_SCREEN_FRACTION = 0.9f;
  private static final float TILT_SCALE              = 0.8f;
  private static final float MAX_SCALE               = 100.0f; //
  private static final float NEEDLE_SCALE_WIDTH      = 16.0f;
  private static final float NEEDLE_SCALE_LENGTH     = 180.0f;
  private static final float PIN_SCALE               = 8.0f;
  private static final float PIN_HIGLIGHT_SCALE      = 10.0f;
  private static final float THICK_LINE              = 3.0f;
  private static final float MEDIUM_LINE             = 2.0f;
  private static final float THIN_LINE               = 1.0f;
  private static final float FINE_LINE               = 1.0f;
  private static final  float TILT_CUTOFF             = 45.0f;

  private final Paint mPinHighlightPaint;
  private final Paint mTextPaint;
  private final Paint mLinePaint;
  private final Paint mNorthPaint;
  private final Paint mSouthPaint;
  private final Paint mPinPaint;
  private       Path  mHalfNeedlePath;
  private       float mRadius;
  private       int   mWidth;
  private       int   mHeight;

  private Camera mCamera;
  private float[] mEulerAngles = {0.0f, 0.0f, 1.0f};
  private Matrix  mMatrix      = new Matrix();
  private float   mScale       = 1.0f;
  private int mDisplayRotation;

  public CompassView(Context context) {
    this(context, null);
  }

  public CompassView(Context context, AttributeSet attrs) {
    this(context, attrs, 0);
  }

  public CompassView(Context context, AttributeSet attrs, int style) {
    super(context, attrs, style);

    mCamera = new Camera();

    mLinePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
    mLinePaint.setColor(Color.WHITE);
    mLinePaint.setStrokeWidth(4.0f);
    mLinePaint.setStyle(Paint.Style.STROKE);

    mNorthPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
    mNorthPaint.setColor(Color.RED);

    mSouthPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
    mSouthPaint.setColor(Color.WHITE);

    mPinPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
    mPinPaint.setColor(Color.GRAY);

    mPinHighlightPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
    mPinHighlightPaint.setColor(Color.LTGRAY);

    mTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.LINEAR_TEXT_FLAG | Paint.SUBPIXEL_TEXT_FLAG);
    mTextPaint.setColor(Color.WHITE);
    mTextPaint.setTextAlign(Paint.Align.CENTER);

  }



  @Override
  protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    int width = MeasureSpec.getSize(widthMeasureSpec);
    int height = MeasureSpec.getSize(heightMeasureSpec);

    if (width > height) {
      setMeasuredDimension(height, height);
    } else {
      setMeasuredDimension(width, width);
    }
  }

  @Override
  protected void onSizeChanged(int w, int h, int oldw, int oldh) {
    super.onSizeChanged(w, h, oldw, oldh);
    mWidth = w;
    mHeight = h;

    mRadius = ((w > h) ? h : w) * COMPASS_SCREEN_FRACTION * 0.5f;
    mScale = mRadius / MAX_SCALE;

    mHalfNeedlePath = new Path();
    mHalfNeedlePath.moveTo(0.0f, 0.0f);
    mHalfNeedlePath.lineTo(0.5f * NEEDLE_SCALE_WIDTH * mScale, 0.0f);
    mHalfNeedlePath.lineTo(0.0f, -0.5f * NEEDLE_SCALE_LENGTH * mScale);
    mHalfNeedlePath.lineTo(-0.5f * NEEDLE_SCALE_WIDTH * mScale, 0.0f);
    mHalfNeedlePath.setFillType(Path.FillType.WINDING);

    WindowManager windowManager = (WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE);
    mDisplayRotation = windowManager.getDefaultDisplay().getRotation();
  }

  @Override
  protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);

    canvas.translate(mWidth / 2.0f, mHeight / 2.0f);

    float xRotation = 0.0f, yRotation = 0.0f, zRotation = 0.0f;
    switch (mDisplayRotation) {
      case Surface.ROTATION_0:
        xRotation = 180.0f*(mEulerAngles[1] / (float) Math.PI);
        yRotation = 180.0f*(mEulerAngles[2] / (float) Math.PI);
        zRotation = 180.0f*(mEulerAngles[0] / (float) Math.PI);
        break;
      case Surface.ROTATION_90:
        xRotation = 180.0f*(mEulerAngles[2] / (float) Math.PI);
        yRotation = -180.0f*(mEulerAngles[1] / (float) Math.PI);
        zRotation = 180.0f*((mEulerAngles[0] + (float)Math.PI*0.5f) / (float) Math.PI);
        break;
      case Surface.ROTATION_180:
        xRotation = -180.0f*(mEulerAngles[1] / (float) Math.PI);
        yRotation = -180.0f*(mEulerAngles[2] / (float) Math.PI);
        zRotation = 180.0f*((mEulerAngles[0] + (float)Math.PI) / (float) Math.PI);
        break;
      case Surface.ROTATION_270:
        xRotation = -180.0f*(mEulerAngles[2] / (float) Math.PI);
        yRotation = +180.0f*(mEulerAngles[1] / (float) Math.PI);
        zRotation = 180.0f*((mEulerAngles[0] + (float)Math.PI*1.5f) / (float) Math.PI);
        break;
    }
    final boolean tilted = Math.abs(xRotation) > TILT_CUTOFF || Math.abs(yRotation) > TILT_CUTOFF;

    if (tilted) {
      canvas.drawText("Heading: " + String.format("%.0f",zRotation) + " deg", 0.0f, -70.0f * mScale, mTextPaint);
    }

    mCamera.save();
    mCamera.setLocation(0.0f, 0.0f, 40.0f);
    mCamera.rotate(
        0.0f,
        +TILT_SCALE * yRotation,
        0.0f);
    mCamera.rotate(
        +TILT_SCALE * xRotation,
        0.0f,
        0.0f
    );
    mCamera.getMatrix(mMatrix);
    mCamera.restore();
    canvas.concat(mMatrix);

    mLinePaint.setStrokeWidth(MEDIUM_LINE * mScale);
    canvas.drawCircle(0.0f, 0.0f, mRadius, mLinePaint);

    for (int i = 0; i < 360; i += 5) {
      float x = (float) Math.sin(Math.PI / 180.0 * (double) i);
      float y = (float) -Math.cos(Math.PI / 180.0 * (double) i);

      float frac = 1.0f;

      if (i % 90 == 0) {
        mLinePaint.setStrokeWidth(THICK_LINE * mScale);
        frac = 0.88f;
      } else if (i % 30 == 0) {
        mLinePaint.setStrokeWidth(MEDIUM_LINE * mScale);
        frac = 0.90f;
      } else if (i % 10 == 0) {
        mLinePaint.setStrokeWidth(THIN_LINE * mScale);
        frac = 0.92f;
      } else {
        mLinePaint.setStrokeWidth(FINE_LINE * mScale);
        frac = 0.94f;
      }
      canvas.drawLine(+x * mRadius, -y * mRadius, +x * mRadius * frac, -y * mRadius * frac, mLinePaint);
    }


    canvas.save();
    canvas.rotate(-zRotation);
    canvas.drawPath(mHalfNeedlePath, mNorthPaint);
    canvas.rotate(+180.0f);
    canvas.drawPath(mHalfNeedlePath, mSouthPaint);
    canvas.restore();

    canvas.drawCircle(0.0f, 0.0f, 0.5f * PIN_HIGLIGHT_SCALE * mScale, mPinPaint);
    canvas.drawCircle(0.0f, 0.0f, 0.5f * PIN_SCALE * mScale, mPinHighlightPaint);
    mTextPaint.setTextSize(15.0f * mScale);


//    if (mHeadingTextView != null) {
//      mHeadingTextView.setText("Heading: " + String.format("%.0f",zRotation) + " deg");
//    }

  }

  public void updateOrientation(float[] eulerAngles) {
    mEulerAngles = Arrays.copyOf(eulerAngles, eulerAngles.length);

    postInvalidate();
  }
}




Java Source Code List

com.hulzenga.ioi.android.AppActivity.java
com.hulzenga.ioi.android.AppDetailsDialog.java
com.hulzenga.ioi.android.App.java
com.hulzenga.ioi.android.TableOfContentsActivity.java
com.hulzenga.ioi.android.app_001.HelloWorldActivity.java
com.hulzenga.ioi.android.app_002.Ball.java
com.hulzenga.ioi.android.app_002.BouncyBallsActivity.java
com.hulzenga.ioi.android.app_002.BouncyBallsView.java
com.hulzenga.ioi.android.app_003.MonsterDatabaseActivity.java
com.hulzenga.ioi.android.app_003.MonsterEditDialog.java
com.hulzenga.ioi.android.app_003.MonsterGenerator.java
com.hulzenga.ioi.android.app_003.MonsterListAdapter.java
com.hulzenga.ioi.android.app_003.database.MonsterContract.java
com.hulzenga.ioi.android.app_003.database.MonsterDatabaseHelper.java
com.hulzenga.ioi.android.app_003.database.MonsterProvider.java
com.hulzenga.ioi.android.app_004.BouncyBall3dActivity.java
com.hulzenga.ioi.android.app_004.BouncyBall3dGLSurfaceView.java
com.hulzenga.ioi.android.app_004.BouncyBall3dRenderer.java
com.hulzenga.ioi.android.app_004.BouncyBallGame.java
com.hulzenga.ioi.android.app_005.ElementActivity.java
com.hulzenga.ioi.android.app_005.ElementAdapter.java
com.hulzenga.ioi.android.app_005.ElementAnimator.java
com.hulzenga.ioi.android.app_005.ElementSnakeView.java
com.hulzenga.ioi.android.app_005.ElementView.java
com.hulzenga.ioi.android.app_005.Element.java
com.hulzenga.ioi.android.app_006.EmptyFragment.java
com.hulzenga.ioi.android.app_006.ExposureFragment.java
com.hulzenga.ioi.android.app_006.SettingChangeListener.java
com.hulzenga.ioi.android.app_006.SettingIconFragment.java
com.hulzenga.ioi.android.app_006.SettingMenuFragment.java
com.hulzenga.ioi.android.app_006.SettingMenuLvl2Fragment.java
com.hulzenga.ioi.android.app_006.Setting.java
com.hulzenga.ioi.android.app_006.SimpleCameraActivity.java
com.hulzenga.ioi.android.app_006.SimpleCameraPreview.java
com.hulzenga.ioi.android.app_007.ButtonsFragment.java
com.hulzenga.ioi.android.app_007.HighScores.java
com.hulzenga.ioi.android.app_007.LinksFragment.java
com.hulzenga.ioi.android.app_007.Menu.java
com.hulzenga.ioi.android.app_007.Review.java
com.hulzenga.ioi.android.app_007.Score.java
com.hulzenga.ioi.android.app_007.StatusFragment.java
com.hulzenga.ioi.android.app_007.WikiGameActivity.java
com.hulzenga.ioi.android.app_007.Wiki.java
com.hulzenga.ioi.android.app_008.OverheidActivity.java
com.hulzenga.ioi.android.app_008.OverheidFeedAdapter.java
com.hulzenga.ioi.android.app_008.OverheidFeedFragment.java
com.hulzenga.ioi.android.app_008.OverheidFeedItem.java
com.hulzenga.ioi.android.app_008.OverheidFeed.java
com.hulzenga.ioi.android.app_008.OverheidPagerAdapter.java
com.hulzenga.ioi.android.app_009.ThumbsUpActivity.java
com.hulzenga.ioi.android.app_009.ThumbsUpServer.java
com.hulzenga.ioi.android.app_009.ThumbsUpService.java
com.hulzenga.ioi.android.app_010.CompassActivity.java
com.hulzenga.ioi.android.app_010.CompassDetailsView.java
com.hulzenga.ioi.android.app_010.CompassView.java
com.hulzenga.ioi.android.util.Constrain.java
com.hulzenga.ioi.android.util.DeveloperTools.java
com.hulzenga.ioi.android.util.FileManager.java
com.hulzenga.ioi.android.util.ScreenMetrics.java
com.hulzenga.ioi.android.util.open_gl.ColorFunctionFactory.java
com.hulzenga.ioi.android.util.open_gl.ColorFunction.java
com.hulzenga.ioi.android.util.open_gl.ShaderTools.java
com.hulzenga.ioi.android.util.open_gl.engine.NodeController.java
com.hulzenga.ioi.android.util.open_gl.engine.SceneGraph.java
com.hulzenga.ioi.android.util.open_gl.engine.SceneNode.java
com.hulzenga.ioi.android.util.open_gl.geometry.Box.java
com.hulzenga.ioi.android.util.open_gl.geometry.Cylinder.java
com.hulzenga.ioi.android.util.open_gl.geometry.Geometry.java
com.hulzenga.ioi.android.util.open_gl.geometry.Grid.java
com.hulzenga.ioi.android.util.open_gl.geometry.Sphere.java
com.hulzenga.ioi.android.util.open_gl.geometry.Transform.java
com.hulzenga.ioi.android.util.open_gl.vector.Vec3.java
com.hulzenga.ioi.android.util.open_gl.vector.Vec4.java
fi.iki.elonen.NanoHTTPD.java