RotatorView.java :  » UnTagged » rotator » org » duyi » rotator » view » Android Open Source

Android Open Source » UnTagged » rotator 
rotator » org » duyi » rotator » view » RotatorView.java
package org.duyi.rotator.view;

import java.util.Random;

import org.duyi.rotator.R;
import org.duyi.rotator.RotatorActivity;

import android.content.Context;
import android.content.res.Configuration;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Path.FillType;
import android.graphics.RectF;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;

/**
 * @Author Yi Du <duyi001@gmail.com>
 * @Date 2011-2-22
 */
public class RotatorView extends View {
  private static final String TAG = "RotatorView";
  private RotatorActivity rotator;
  private static final int SELECTED_ADD = 0;
  private static final int SELECTED_NONE = -1;
  private static final int ROTATE_INTERVAL = 2;// 2ms
  private static final int DAMP = 5;// 
  private static final int ROTATE_MSG = 5;

  private int[] colors = { getResources().getColor(R.color.LightPink), 
      getResources().getColor(R.color.RoyalBlue),
      getResources().getColor(R.color.LightGreen), 
      getResources().getColor(R.color.Gold), 
      getResources().getColor(R.color.LightSalmon), 
      getResources().getColor(R.color.Cyan), 
      getResources().getColor(R.color.Violet), 
      getResources().getColor(R.color.PeachPuff), 
      getResources().getColor(R.color.LightSteelBlue)};
  
  private static int currentRotation = 0;
  private RotationHandler handler;
  private Paint paint;
  private Bitmap bitmapAdd;
  private Bitmap bitmapTipCenter;
  private Random random;

  private RectF rectBigCircle;
  private RectF rectSmallCircle;
  private float widthPixels;
  private float heightPixels;
  private float borderSize;
  float smillCircleStart;
  float radiusOfSmallCircle;
  float radiusOfBigCircle;
  private float centerX;
  private float centerY;

  private int currentRotationTime = -1;// -1 means no value

  private boolean isShowTip;
  private boolean isShowPressCenter;
  private boolean isShowPressModify = false;; 
  private boolean isShowCrossToRotate = false;

  /**
   * @param context
   */
  public RotatorView(Context context) {
    this(context, true);    
  }
  
  /**
   * @param context
   * @param isShowTip
   */
  public RotatorView(Context context, boolean isShowTip) {
    super(context);
    rotator = (RotatorActivity) context;
    this.isShowTip = isShowTip;
    initLogic();
  }
  private void initLogic(){
    //
    isShowPressCenter = isShowTip;
    //
    handler = new RotationHandler();
    paint = new Paint();
    random = new Random(System.currentTimeMillis());

    if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) {
      heightPixels = getContext().getResources().getDisplayMetrics().widthPixels;
      widthPixels = getContext().getResources().getDisplayMetrics().heightPixels;
    } else {
      heightPixels = getContext().getResources().getDisplayMetrics().heightPixels;
      widthPixels = getContext().getResources().getDisplayMetrics().widthPixels;
    }
    centerX = centerY = widthPixels / 2.0f;
    borderSize = widthPixels / 16;
    rectBigCircle = new RectF(borderSize, borderSize, widthPixels
        - borderSize, widthPixels - borderSize);
    smillCircleStart = borderSize * 5.5f;
    radiusOfSmallCircle = borderSize * 2.5f;
    radiusOfBigCircle = borderSize * 7.5f;
    rectSmallCircle = new RectF(smillCircleStart, smillCircleStart,
        widthPixels - smillCircleStart, widthPixels - smillCircleStart);

    // image at center
    bitmapAdd = BitmapFactory.decodeResource(rotator.getResources(),
        R.drawable.arrow);
    bitmapAdd = Bitmap.createScaledBitmap(bitmapAdd,
        (int) radiusOfSmallCircle * 2, (int) radiusOfSmallCircle * 3,
        true);
    if(isShowPressCenter){
      bitmapTipCenter = BitmapFactory
        .decodeResource(rotator.getResources(), R.drawable.pressme);
    }
    Log.d(TAG, "pixel(width,height,borderSize):" + widthPixels + ","
        + heightPixels + "," + borderSize);

  }

  @Override
  protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    // TODO Animination 
    paint.setAntiAlias(true);
    // 
    paint.setColor(Color.DKGRAY);
    paint.setStyle(Paint.Style.STROKE);
    paint.setStrokeWidth(5);
    canvas.drawCircle(centerX, centerY, radiusOfBigCircle + 1, paint);
    paint.setStrokeWidth(0.5f);
    int numOfPie = rotator.getChooseList().size();
    if (numOfPie == 0) {
      // draw the big circle
      paint.setColor(Color.GRAY);
      canvas.drawCircle(centerX, centerY, radiusOfBigCircle, paint);
    } else if (numOfPie > 0) {
      float angleOfPie = 360 / numOfPie;
      Path testPath;
      paint.setStyle(Paint.Style.FILL_AND_STROKE);
      for (int i = 0; i < numOfPie && i < colors.length; i++) {
        testPath = new Path();
        testPath.setFillType(FillType.EVEN_ODD);
        paint.setColor(colors[i]);
        paint.setAlpha(100);
        testPath.addArc(rectBigCircle,
            currentRotation + i * angleOfPie, angleOfPie);
        testPath.lineTo(centerX, centerY);
        testPath.close();
        testPath.addArc(rectSmallCircle, currentRotation + (i + 1)
            * angleOfPie, -angleOfPie);
        testPath.lineTo(centerX, centerY);
        testPath.close();
        canvas.drawPath(testPath, paint);
        
        paint.setColor(Color.BLACK);
        paint.setTextSize(getResources().getDimension(R.dimen.sizePieText));
        canvas.drawTextOnPath(rotator.getChooseList().get(i).getName(),
            testPath, getResources().getDimension(R.dimen.sizePieText),
            getResources().getDimension(R.dimen.sizePieText) * 1.5f, paint);
      }
    } else {

    }

    canvas.drawBitmap(bitmapAdd, smillCircleStart, smillCircleStart
        - bitmapAdd.getWidth() / 2, null);
    if(isShowPressCenter){
      canvas.drawBitmap(bitmapTipCenter, centerX, centerY-bitmapTipCenter.getHeight(), null);
    }
    if(isShowPressModify){
      //TODO show tip
    }
    if(isShowCrossToRotate){
      //TODO show tip
    }
  }

  private boolean touchMoving = false;
  @Override
  public boolean onTouchEvent(MotionEvent event) {
    int selected = getSelected(event.getX(), event.getY());
    if (event.getAction() == MotionEvent.ACTION_MOVE) {
      touchMoving = true;
      Log.i(TAG, "action_move");
      int numOfPie = rotator.getChooseList().size();
      if (numOfPie == 0)
        return true;
      invalidate();
    } else if (event.getAction() == MotionEvent.ACTION_UP) {
      if (touchMoving) {
        for (int i = 1; i <= DAMP; i++) {
          Message message = new Message();
          message.arg1 = ROTATE_MSG;
          message.what = i;
          handler.sendMessageDelayed(message, i * ROTATE_INTERVAL);
          handler.sendEmptyMessageDelayed(i, getCurrentRotationTime()
              * (i + 1));
        }

        touchMoving = false;
        return true;
      }
    }
    if (selected == SELECTED_ADD) {
      if (event.getAction() == MotionEvent.ACTION_DOWN) {
        // TODO change pic
        Log.i(TAG, "action_down");
      } else if (event.getAction() == MotionEvent.ACTION_UP) {
        // TODO change image and add new choice
        rotator.showAddActivity();
        if(isShowPressCenter)
          isShowPressCenter = false;
        if(isShowTip && !isShowPressModify){
          isShowPressModify = true;
        }
        Log.i(TAG, "action_up");
      }
    } else if (selected == SELECTED_NONE) {

    } else {
      if (event.getAction() == MotionEvent.ACTION_DOWN) {
        // TODO change pic
        Log.i(TAG, "selected action_down");
      } else if (event.getAction() == MotionEvent.ACTION_UP) {
        rotator.showModifyActivity(selected);
        if(isShowPressModify)
          isShowPressModify = false;
        Log.i(TAG, "selected action_up");
      }
    }
    return true;

  }

  private int getCurrentRotationTime() {
    if (currentRotationTime == -1) {
      currentRotationTime = ROTATE_INTERVAL * 100
          * (random.nextInt(5) + 5);
      Log.d(TAG, "currentRotationTime:" + getCurrentRotationTime());
    }
    return currentRotationTime;
  }

  public void setCurrentRotationTime(int time) {
    this.currentRotationTime = time;
  }

  /**
   * calculate which pie is selected
   * 
   * @param x
   * @param y
   * @return index of the selected pie. 0 if center is selected. -1 if none is
   *         selected.
   */
  private int getSelected(float x, float y) {
    double distanceToCenter = Math.sqrt((x - centerX) * (x - centerX)
        + (y - centerY) * (y - centerY));
    if (distanceToCenter < radiusOfSmallCircle)
      return SELECTED_ADD;
    if (distanceToCenter > radiusOfBigCircle)
      return SELECTED_NONE;
    double angle;
    if (x == centerX && y == centerY) {
      return -1;
    } else if (x == centerX && y > centerY) {
      angle = Math.PI / 2;
    } else if (x == centerX && y < centerY) {
      angle = Math.PI * 3 / 2;
    } else if (x > centerX && y == centerY) {
      angle = 0;
    } else if (x < centerX && y == centerY) {
      angle = Math.PI;
    } else {
      float tan = (y - centerX) / (x - centerY);
      angle = (float) Math.atan(tan);
      if (x < centerX) {
        angle += Math.PI;
      }
    }
    double currentAngle = (angle - currentRotation * Math.PI / 180)
        % (2 * Math.PI);
    if (currentAngle < 0)
      currentAngle += Math.PI * 2;
    int index = (int) (currentAngle / ((2 * Math.PI) / rotator
        .getChooseList().size())) + 1;
    Log.d(TAG, "listsize:" + rotator.getChooseList().size() + "index : "
        + index + ";currentAngle:" + currentAngle);
    return index;
  }

  public void rotateOneDegree() {
    currentRotation++;
    invalidate();
  }

  /**
   * 
   * @return index of the pointer pointing
   */
  private int pointerIndex() {
    float x = centerX;
    float y = (radiusOfBigCircle + radiusOfSmallCircle) / 2;
    return getSelected(x, y);
  }

  class RotationHandler extends Handler {
    public RotationHandler() {

    }

    @Override
    public void handleMessage(Message msg) {
      super.handleMessage(msg);
      if (msg.arg1 == ROTATE_MSG) {
        rotateOneDegree();
        Message message = new Message();
        message.arg1 = ROTATE_MSG;
        message.what = msg.what;
        handler.sendMessageDelayed(message, ROTATE_INTERVAL);
      } else {
        removeMessages(msg.what);
        Log.d(TAG, "remove msg :" + msg.what);
        if (msg.what == DAMP) {
          int index = pointerIndex();
          rotator.showResultActivity(index);
        }
      }
    }

  }

  /**
   * remove all handler of the view, stop it's rotation
   */
  public void removeAllHandler() {
    if (handler != null) {
      for (int i = 1; i <= DAMP; i++) {
        handler.removeMessages(i);
        Log.i(TAG, "remove message :" + i);
      }
    }
  }
}
java2s.com  | Contact Us | Privacy Policy
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.