pageCurlSample1.java
PageCurlView.java
- package com.pageCurlSample1;
- import android.app.Activity;
- import android.os.Bundle;
- public class pageCurlSample1 extends Activity {
- /** Called when the activity is first created. */
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- PageCurlView curlView;
- curlView = new PageCurlView(this);
- setContentView(curlView);
- }
- @Override
- public void onDestroy(){
- super.onDestroy();
- System.gc();
- finish();
- }
- }
- package com.pageCurlSample1;
- import java.util.ArrayList;
- import android.content.Context;
- import android.graphics.Bitmap;
- import android.graphics.BitmapFactory;
- import android.graphics.Canvas;
- import android.graphics.Color;
- import android.graphics.Paint;
- import android.graphics.Paint.Style;
- import android.graphics.Path;
- import android.graphics.Rect;
- import android.os.Handler;
- import android.os.Message;
- import android.text.TextPaint;
- import android.view.MotionEvent;
- import android.view.View;
- /**
- *
- * @author Moritz 'Moss' Wundke (b.thax.dcg@gmail.com)
- *
- */
- public class PageCurlView extends View {
- /** Our Log tag */
- //private final static String TAG = "PageCurlView";
- // Debug text paint stuff
- private Paint mTextPaint;
- private TextPaint mTextPaintShadow;
- /** Px / Draw call */
- private int mCurlSpeed;
- /** Fixed update time used to create a smooth curl animation */
- private int mUpdateRate;
- /** The initial offset for x and y axis movements */
- private int mInitialEdgeOffset;
- /** The mode we will use */
- private int mCurlMode;
- /** Simple curl mode. Curl target will move only in one axis. */
- public static final int CURLMODE_SIMPLE = 0;
- /** Dynamic curl mode. Curl target will move on both X and Y axis. */
- public static final int CURLMODE_DYNAMIC = 1;
- /** Enable/Disable debug mode */
- private boolean bEnableDebugMode = false;
- /** The context which owns us */
- //private WeakReference
mContext; - /** Handler used to auto flip time based */
- private FlipAnimationHandler mAnimationHandler;
- /** Maximum radius a page can be flipped, by default it's the width of the view */
- private float mFlipRadius;
- /** Point used to move */
- private Vector2D mMovement;
- /** The finger position */
- private Vector2D mFinger;
- /** Movement point form the last frame */
- private Vector2D mOldMovement;
- /** Page curl edge */
- private Paint mCurlEdgePaint;
- /** Our points used to define the current clipping paths in our draw call */
- private Vector2D mA, mB, mC, mD, mE, mF, mOldF, mOrigin;
- /** Left and top offset to be applied when drawing */
- //private int mCurrentLeft, mCurrentTop;
- /** If false no draw call has been done */
- private boolean bViewDrawn;
- /** Defines the flip direction that is currently considered */
- private boolean bFlipRight;
- /** If TRUE we are currently auto-flipping */
- private boolean bFlipping;
- /** TRUE if the user moves the pages */
- //private boolean bUserMoves;
- /** Used to control touch input blocking */
- private boolean bBlockTouchInput = false;
- /** Enable input after the next draw event */
- private boolean bEnableInputAfterDraw = false;
- /** LAGACY The current foreground */
- private Bitmap mForeground;
- /** LAGACY The current background */
- private Bitmap mBackground;
- /** LAGACY List of pages, this is just temporal */
- private ArrayList
mPages; - /** LAGACY Current selected page */
- private int mIndex = 0;
- /**
- * Inner class used to represent a 2D point.
- */
- private class Vector2D
- {
- public float x,y;
- public Vector2D(float x, float y)
- {
- this.x = x;
- this.y = y;
- }
- @Override
- public String toString() {
- // TODO Auto-generated method stub
- return "("+this.x+","+this.y+")";
- }
- public boolean equals(Object o) {
- if (o instanceof Vector2D) {
- Vector2D p = (Vector2D) o;
- return p.x == x && p.y == y;
- }
- return false;
- }
- public Vector2D sum(Vector2D b) {
- return new Vector2D(x+b.x,y+b.y);
- }
- public Vector2D sub(Vector2D b) {
- return new Vector2D(x-b.x,y-b.y);
- }
- public float distanceSquared(Vector2D other) {
- float dx = other.x - x;
- float dy = other.y - y;
- return (dx * dx) + (dy * dy);
- }
- public float distance(Vector2D other) {
- return (float) Math.sqrt(distanceSquared(other));
- }
- public float dotProduct(Vector2D other) {
- return other.x * x + other.y * y;
- }
- public Vector2D normalize() {
- float magnitude = (float) Math.sqrt(dotProduct(this));
- return new Vector2D(x / magnitude, y / magnitude);
- }
- public Vector2D mult(float scalar) {
- return new Vector2D(x*scalar,y*scalar);
- }
- }
- /**
- * Inner class used to make a fixed timed animation of the curl effect.
- */
- class FlipAnimationHandler extends Handler {
- @Override
- public void handleMessage(Message msg) {
- PageCurlView.this.FlipAnimationStep();
- }
- public void sleep(long millis) {
- this.removeMessages(0);
- sendMessageDelayed(obtainMessage(0), millis);
- }
- }
- /**
- * Base
- * @param context
- */
- public PageCurlView(Context context) {
- super(context);
- init(context);
- ResetClipEdge();
- }
- /**
- * Initialize the view
- */
- private final void init(Context context) {
- // Foreground text paint
- mTextPaint = new Paint();
- mTextPaint.setAntiAlias(true);
- mTextPaint.setTextSize(16);
- mTextPaint.setColor(0xFF000000);
- // The shadow
- mTextPaintShadow = new TextPaint();
- mTextPaintShadow.setAntiAlias(true);
- mTextPaintShadow.setTextSize(16);
- mTextPaintShadow.setColor(0x00000000);
- // Cache the context
- //mContext = new WeakReference
(context); - // Base padding
- setPadding(3, 3, 3, 3);
- // The focus flags are needed
- setFocusable(true);
- setFocusableInTouchMode(true);
- mMovement = new Vector2D(0,0);
- mFinger = new Vector2D(0,0);
- mOldMovement = new Vector2D(0,0);
- // Create our curl animation handler
- mAnimationHandler = new FlipAnimationHandler();
- // Create our edge paint
- mCurlEdgePaint = new Paint();
- mCurlEdgePaint.setColor(Color.WHITE);
- mCurlEdgePaint.setAntiAlias(true);
- mCurlEdgePaint.setStyle(Paint.Style.FILL);
- mCurlEdgePaint.setShadowLayer(10, -5, 5, 0x99000000);
- // Set the default props, those come from an XML :D
- mCurlSpeed = 30;//30
- mUpdateRate = 33;//33
- mInitialEdgeOffset = 50;//20//초기 edge 부분의 값
- mCurlMode = 1;
- // LEGACY PAGE HANDLING!
- // Create pages
- mPages = new ArrayList
(); - mPages.add(BitmapFactory.decodeResource(getResources(), R.drawable.page1));
- mPages.add(BitmapFactory.decodeResource(getResources(), R.drawable.page2));
- // Create some sample images
- mForeground = mPages.get(0);
- mBackground = mPages.get(1);
- }
- /**
- * Reset points to it's initial clip edge state
- */
- public void ResetClipEdge()
- {
- // Set our base movement
- mMovement.x = mInitialEdgeOffset;
- mMovement.y = mInitialEdgeOffset;
- mOldMovement.x = 0;
- mOldMovement.y = 0;
- // Now set the points
- // TODO: OK, those points MUST come from our measures and
- // the actual bounds of the view!
- mA = new Vector2D(mInitialEdgeOffset, 0);
- mB = new Vector2D(this.getWidth(), this.getHeight());
- mC = new Vector2D(this.getWidth(), 0);
- mD = new Vector2D(0, 0);
- mE = new Vector2D(0, 0);
- mF = new Vector2D(0, 0);
- mOldF = new Vector2D(0, 0);
- // The movement origin point
- mOrigin = new Vector2D(this.getWidth(), 0);
- }
- /**
- * See if the current curl mode is dynamic
- * @return TRUE if the mode is CURLMODE_DYNAMIC, FALSE otherwise
- */
- public boolean IsCurlModeDynamic()
- {
- return mCurlMode == CURLMODE_DYNAMIC;
- }
- /**
- * Set the curl speed.
- * @param curlSpeed - New speed in px/frame
- * @throws IllegalArgumentException if curlspeed < 1
- */
- public void SetCurlSpeed(int curlSpeed)
- {
- if ( curlSpeed < 1 )
- throw new IllegalArgumentException("curlSpeed must be greated than 0");
- mCurlSpeed = curlSpeed;
- }
- /**
- * Get the current curl speed
- * @return int - Curl speed in px/frame
- */
- public int GetCurlSpeed()
- {
- return mCurlSpeed;
- }
- /**
- * Set the update rate for the curl animation
- * @param updateRate - Fixed animation update rate in fps
- * @throws IllegalArgumentException if updateRate < 1
- */
- public void SetUpdateRate(int updateRate)
- {
- if ( updateRate < 1 )
- throw new IllegalArgumentException("updateRate must be greated than 0");
- mUpdateRate = updateRate;
- }
- /**
- * Get the current animation update rate
- * @return int - Fixed animation update rate in fps
- */
- public int GetUpdateRate()
- {
- return mUpdateRate;
- }
- /**
- * Set the initial pixel offset for the curl edge
- * @param initialEdgeOffset - px offset for curl edge
- * @throws IllegalArgumentException if initialEdgeOffset < 0
- */
- public void SetInitialEdgeOffset(int initialEdgeOffset)
- {
- if ( initialEdgeOffset < 0 )
- throw new IllegalArgumentException("initialEdgeOffset can not negative");
- mInitialEdgeOffset = initialEdgeOffset;
- }
- /**
- * Get the initial pixel offset for the curl edge
- * @return int - px
- */
- public int GetInitialEdgeOffset()
- {
- return mInitialEdgeOffset;
- }
- /**
- * Set the curl mode.
- * @see #CURLMODE_SIMPLE
- * @see #CURLMODE_DYNAMIC
- * @param curlMode
- * @throws IllegalArgumentException if curlMode is invalid
- */
- public void SetCurlMode(int curlMode)
- {
- if ( curlMode != CURLMODE_SIMPLE &&
- curlMode != CURLMODE_DYNAMIC )
- throw new IllegalArgumentException("Invalid curlMode");
- mCurlMode = curlMode;
- }
- /**
- * Return an integer that represents the current curl mode.
- * @see #CURLMODE_SIMPLE
- * @see #CURLMODE_DYNAMIC
- * @return int - current curl mode
- */
- public int GetCurlMode()
- {
- return mCurlMode;
- }
- /**
- * Enable debug mode. This will draw a lot of data in the view so you can track what is happening
- * @param bFlag - boolean flag
- */
- public void SetEnableDebugMode(boolean bFlag)
- {
- bEnableDebugMode = bFlag;
- }
- /**
- * Check if we are currently in debug mode.
- * @return boolean - If TRUE debug mode is on, FALSE otherwise.
- */
- public boolean IsDebugModeEnabled()
- {
- return bEnableDebugMode;
- }
- /**
- * @see android.view.View#measure(int, int)
- */
- @Override
- protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
- int finalWidth, finalHeight;
- finalWidth = measureWidth(widthMeasureSpec);
- finalHeight = measureHeight(heightMeasureSpec);
- setMeasuredDimension(finalWidth, finalHeight);
- }
- /**
- * Determines the width of this view
- * @param measureSpec A measureSpec packed into an int
- * @return The width of the view, honoring constraints from measureSpec
- */
- private int measureWidth(int measureSpec) {
- int result = 0;
- int specMode = MeasureSpec.getMode(measureSpec);
- int specSize = MeasureSpec.getSize(measureSpec);
- if (specMode == MeasureSpec.EXACTLY) {
- // We were told how big to be
- result = specSize;
- } else {
- // Measure the text
- result = specSize;
- }
- return result;
- }
- /**
- * Determines the height of this view
- * @param measureSpec A measureSpec packed into an int
- * @return The height of the view, honoring constraints from measureSpec
- */
- private int measureHeight(int measureSpec) {
- int result = 0;
- int specMode = MeasureSpec.getMode(measureSpec);
- int specSize = MeasureSpec.getSize(measureSpec);
- if (specMode == MeasureSpec.EXACTLY) {
- // We were told how big to be
- result = specSize;
- } else {
- // Measure the text (beware: ascent is a negative number)
- result = specSize;
- }
- return result;
- }
- //---------------------------------------------------------------
- // Curling. This handles touch events, the actual curling
- // implementations and so on.
- //---------------------------------------------------------------
- @Override
- public boolean onTouchEvent(MotionEvent event) {
- if (!bBlockTouchInput) {
- // Get our finger position
- mFinger.x = event.getX();
- mFinger.y = event.getY();
- int width = getWidth();
- // Depending on the action do what we need to
- switch (event.getAction()) {
- case MotionEvent.ACTION_DOWN:
- mOldMovement.x = mFinger.x;
- mOldMovement.y = mFinger.y;
- // If we moved over the half of the display flip to next
- if (mOldMovement.x > (width >> 1)) {
- mMovement.x = mInitialEdgeOffset;
- mMovement.y = mInitialEdgeOffset;
- // Set the right movement flag
- bFlipRight = true;
- } else {
- // Set the left movement flag
- bFlipRight = false;
- // go to next previous page
- previousView();
- // Set new movement
- mMovement.x = IsCurlModeDynamic()?width<<1:width;
- mMovement.y = mInitialEdgeOffset;
- }
- break;
- case MotionEvent.ACTION_UP:
- //bUserMoves=false;
- bFlipping=true;
- FlipAnimationStep();
- break;
- case MotionEvent.ACTION_MOVE:
- //bUserMoves=true;
- // Get movement
- mMovement.x -= mFinger.x - mOldMovement.x;
- mMovement.y -= mFinger.y - mOldMovement.y;
- mMovement = CapMovement(mMovement, true);
- // Make sure the y value get's locked at a nice level
- if ( mMovement.y <= 1 )
- mMovement.y = 1;
- // Get movement direction
- if (mFinger.x < mOldMovement.x ) {
- bFlipRight = true;
- } else {
- bFlipRight = false;
- }
- // Save old movement values
- mOldMovement.x = mFinger.x;
- mOldMovement.y = mFinger.y;
- // Force a new draw call
- DoPageCurl();
- this.invalidate();
- break;
- }
- }
- // TODO: Only consume event if we need to.
- return true;
- }
- /**
- * Make sure we never move too much, and make sure that if we
- * move too much to add a displacement so that the movement will
- * be still in our radius.
- * @param radius - radius form the flip origin
- * @param bMaintainMoveDir - Cap movement but do not change the
- * current movement direction
- * @return Corrected point
- */
- private Vector2D CapMovement(Vector2D point, boolean bMaintainMoveDir)
- {
- // Make sure we never ever move too much
- if (point.distance(mOrigin) > mFlipRadius)
- {
- if ( bMaintainMoveDir )
- {
- // Maintain the direction
- point = mOrigin.sum(point.sub(mOrigin).normalize().mult(mFlipRadius));
- }
- else
- {
- // Change direction
- if ( point.x > (mOrigin.x+mFlipRadius))
- point.x = (mOrigin.x+mFlipRadius);
- else if ( point.x < (mOrigin.x-mFlipRadius) )
- point.x = (mOrigin.x-mFlipRadius);
- point.y = (float) (Math.sin(Math.acos(Math.abs(point.x-mOrigin.x)/mFlipRadius))*mFlipRadius);
- }
- }
- return point;
- }
- /**
- * Execute a step of the flip animation
- */
- public void FlipAnimationStep() {
- if ( !bFlipping )
- return;
- int width = getWidth();
- // No input when flipping
- bBlockTouchInput = true;
- // Handle speed
- float curlSpeed = mCurlSpeed;
- if ( !bFlipRight )
- curlSpeed *= -1;
- // Move us
- mMovement.x += curlSpeed;
- mMovement = CapMovement(mMovement, false);
- // Create values
- DoPageCurl();
- // Check for endings :D
- if (mA.x < 1 || mA.x > width - 1) {
- bFlipping = false;
- if (bFlipRight) {
- //SwapViews();
- nextView();
- }
- ResetClipEdge();
- // Create values
- DoPageCurl();
- // Enable touch input after the next draw event
- bEnableInputAfterDraw = true;
- }
- else
- {
- mAnimationHandler.sleep(mUpdateRate);
- }
- // Force a new draw call
- this.invalidate();
- }
- /**
- * Do the page curl depending on the methods we are using
- */
- private void DoPageCurl()
- {
- if(bFlipping){
- if ( IsCurlModeDynamic() )
- doDynamicCurl();
- else
- doSimpleCurl();
- } else {
- if ( IsCurlModeDynamic() )
- doDynamicCurl();
- else
- doSimpleCurl();
- }
- }
- /**
- * Do a simple page curl effect
- */
- private void doSimpleCurl() {
- int width = getWidth();
- int height = getHeight();
- // Calculate point A
- mA.x = width - mMovement.x;
- mA.y = height;
- // Calculate point D
- mD.x = 0;
- mD.y = 0;
- if (mA.x > width / 2) {
- mD.x = width;
- mD.y = height - (width - mA.x) * height / mA.x;
- } else {
- mD.x = 2 * mA.x;
- mD.y = 0;
- }
- // Now calculate E and F taking into account that the line
- // AD is perpendicular to FB and EC. B and C are fixed points.
- double angle = Math.atan((height - mD.y) / (mD.x + mMovement.x - width));
- double _cos = Math.cos(2 * angle);
- double _sin = Math.sin(2 * angle);
- // And get F
- mF.x = (float) (width - mMovement.x + _cos * mMovement.x);
- mF.y = (float) (height - _sin * mMovement.x);
- // If the x position of A is above half of the page we are still not
- // folding the upper-right edge and so E and D are equal.
- if (mA.x > width / 2) {
- mE.x = mD.x;
- mE.y = mD.y;
- }
- else
- {
- // So get E
- mE.x = (float) (mD.x + _cos * (width - mD.x));
- mE.y = (float) -(_sin * (width - mD.x));
- }
- }
- /**
- * Calculate the dynamic effect, that one that follows the users finger
- */
- private void doDynamicCurl() {
- int width = getWidth();
- int height = getHeight();
- // F will follow the finger, we add a small displacement
- // So that we can see the edge
- mF.x = width - mMovement.x+0.1f;
- mF.y = height - mMovement.y+0.1f;
- // Set min points
- if(mA.x==0) {
- mF.x= Math.min(mF.x, mOldF.x);
- mF.y= Math.max(mF.y, mOldF.y);
- }
- // Get diffs
- float deltaX = width-mF.x;
- float deltaY = height-mF.y;
- float BH = (float) (Math.sqrt(deltaX * deltaX + deltaY * deltaY) / 2);
- double tangAlpha = deltaY / deltaX;
- double alpha = Math.atan(deltaY / deltaX);
- double _cos = Math.cos(alpha);
- double _sin = Math.sin(alpha);
- mA.x = (float) (width - (BH / _cos));
- mA.y = height;
- mD.y = (float) (height - (BH / _sin));
- mD.x = width;
- mA.x = Math.max(0,mA.x);
- if(mA.x==0) {
- mOldF.x = mF.x;
- mOldF.y = mF.y;
- }
- // Get W
- mE.x = mD.x;
- mE.y = mD.y;
- // Correct
- if (mD.y < 0) {
- mD.x = width + (float) (tangAlpha * mD.y);
- mE.y = 0;
- mE.x = width + (float) (Math.tan(2 * alpha) * mD.y);
- }
- }
- /**
- * Swap between the fore and back-ground.
- */
- /*
- @Deprecated
- private void SwapViews() {
- Bitmap temp = mForeground;
- mForeground = mBackground;
- mBackground = temp;
- }
- */
- /**
- * Swap to next view
- */
- private void nextView() {
- int foreIndex = mIndex + 1;
- if(foreIndex >= mPages.size()) {
- foreIndex = 0;
- }
- int backIndex = foreIndex + 1;
- if(backIndex >= mPages.size()) {
- backIndex = 0;
- }
- mIndex = foreIndex;
- setViews(foreIndex, backIndex);
- }
- /**
- * Swap to previous view
- */
- private void previousView() {
- int backIndex = mIndex;
- int foreIndex = backIndex - 1;
- if(foreIndex < 0) {
- foreIndex = mPages.size()-1;
- }
- mIndex = foreIndex;
- setViews(foreIndex, backIndex);
- }
- /**
- * Set current fore and background
- * @param foreground - Foreground view index
- * @param background - Background view index
- */
- private void setViews(int foreground, int background) {
- mForeground = mPages.get(foreground);
- mBackground = mPages.get(background);
- }
- //---------------------------------------------------------------
- // Drawing methods
- //---------------------------------------------------------------
- @Override
- protected void onDraw(Canvas canvas) {
- // Always refresh offsets
- //mCurrentLeft = getLeft();
- //mCurrentTop = getTop();
- // Translate the whole canvas
- //canvas.translate(mCurrentLeft, mCurrentTop);
- // We need to initialize all size data when we first draw the view
- if ( !bViewDrawn ) {
- bViewDrawn = true;
- onFirstDrawEvent(canvas);
- }
- canvas.drawColor(Color.WHITE);
- // Curl pages
- //DoPageCurl();
- // TODO: This just scales the views to the current
- // width and height. We should add some logic for:
- // 1) Maintain aspect ratio
- // 2) Uniform scale
- // 3) ...
- Rect rect = new Rect();
- rect.left = 0;
- rect.top = 0;
- rect.bottom = getHeight();
- rect.right = getWidth();
- // First Page render
- Paint paint = new Paint();
- // Draw our elements
- drawForeground(canvas, rect, paint);
- drawBackground(canvas, rect, paint);
- drawCurlEdge(canvas);
- // Draw any debug info once we are done
- if ( bEnableDebugMode )
- drawDebug(canvas);
- // Check if we can re-enable input
- if ( bEnableInputAfterDraw )
- {
- bBlockTouchInput = false;
- bEnableInputAfterDraw = false;
- }
- // Restore canvas
- //canvas.restore();
- }
- /**
- * Called on the first draw event of the view
- * @param canvas
- */
- protected void onFirstDrawEvent(Canvas canvas) {
- mFlipRadius = getWidth();
- ResetClipEdge();
- DoPageCurl();
- }
- /**
- * Draw the foreground
- * @param canvas
- * @param rect
- * @param paint
- */
- private void drawForeground( Canvas canvas, Rect rect, Paint paint ) {
- canvas.drawBitmap(mForeground, null, rect, paint);
- // Draw the page number (first page is 1 in real life :D
- // there is no page number 0 hehe)
- drawPageNum(canvas, mIndex);
- }
- /**
- * Create a Path used as a mask to draw the background page
- * @return
- */
- private Path createBackgroundPath() {
- Path path = new Path();
- path.moveTo(mA.x, mA.y);
- path.lineTo(mB.x, mB.y);
- path.lineTo(mC.x, mC.y);
- path.lineTo(mD.x, mD.y);
- path.lineTo(mA.x, mA.y);
- return path;
- }
- /**
- * Draw the background image.
- * @param canvas
- * @param rect
- * @param paint
- */
- private void drawBackground( Canvas canvas, Rect rect, Paint paint ) {
- Path mask = createBackgroundPath();
- // Save current canvas so we do not mess it up
- canvas.save();
- canvas.clipPath(mask);
- canvas.drawBitmap(mBackground, null, rect, paint);
- // Draw the page number (first page is 1 in real life :D
- // there is no page number 0 hehe)
- drawPageNum(canvas, mIndex);
- canvas.restore();
- }
- /**
- * Creates a path used to draw the curl edge in.
- * @return
- */
- private Path createCurlEdgePath() {
- Path path = new Path();
- path.moveTo(mA.x, mA.y);
- path.lineTo(mD.x, mD.y);
- path.lineTo(mE.x, mE.y);
- path.lineTo(mF.x, mF.y);
- path.lineTo(mA.x, mA.y);
- return path;
- }
- /**
- * Draw the curl page edge
- * @param canvas
- */
- private void drawCurlEdge( Canvas canvas )
- {
- Path path = createCurlEdgePath();
- canvas.drawPath(path, mCurlEdgePaint);
- }
- /**
- * Draw page num (let this be a bit more custom)
- * @param canvas
- * @param pageNum
- */
- private void drawPageNum(Canvas canvas, int pageNum)
- {
- mTextPaint.setColor(Color.WHITE);
- String pageNumText = "- "+pageNum+" -";
- drawCentered(canvas, pageNumText,canvas.getHeight()-mTextPaint.getTextSize()-5,mTextPaint,mTextPaintShadow);
- }
- //---------------------------------------------------------------
- // Debug draw methods
- //---------------------------------------------------------------
- /**
- * Draw a text with a nice shadow
- */
- public static void drawTextShadowed(Canvas canvas, String text, float x, float y, Paint textPain, Paint shadowPaint) {
- canvas.drawText(text, x-1, y, shadowPaint);
- canvas.drawText(text, x, y+1, shadowPaint);
- canvas.drawText(text, x+1, y, shadowPaint);
- canvas.drawText(text, x, y-1, shadowPaint);
- canvas.drawText(text, x, y, textPain);
- }
- /**
- * Draw a text with a nice shadow centered in the X axis
- * @param canvas
- * @param text
- * @param y
- * @param textPain
- * @param shadowPaint
- */
- public static void drawCentered(Canvas canvas, String text, float y, Paint textPain, Paint shadowPaint)
- {
- float posx = (canvas.getWidth() - textPain.measureText(text))/2;
- drawTextShadowed(canvas, text, posx, y, textPain, shadowPaint);
- }
- /**
- * Draw debug info
- * @param canvas
- */
- private void drawDebug(Canvas canvas)
- {
- float posX = 10;
- float posY = 20;
- Paint paint = new Paint();
- paint.setStrokeWidth(5);
- paint.setStyle(Style.STROKE);
- paint.setColor(Color.BLACK);
- canvas.drawCircle(mOrigin.x, mOrigin.y, getWidth(), paint);
- paint.setStrokeWidth(3);
- paint.setColor(Color.RED);
- canvas.drawCircle(mOrigin.x, mOrigin.y, getWidth(), paint);
- paint.setStrokeWidth(5);
- paint.setColor(Color.BLACK);
- canvas.drawLine(mOrigin.x, mOrigin.y, mMovement.x, mMovement.y, paint);
- paint.setStrokeWidth(3);
- paint.setColor(Color.RED);
- canvas.drawLine(mOrigin.x, mOrigin.y, mMovement.x, mMovement.y, paint);
- posY = debugDrawPoint(canvas,"A",mA,Color.RED,posX,posY);
- posY = debugDrawPoint(canvas,"B",mB,Color.GREEN,posX,posY);
- posY = debugDrawPoint(canvas,"C",mC,Color.BLUE,posX,posY);
- posY = debugDrawPoint(canvas,"D",mD,Color.CYAN,posX,posY);
- posY = debugDrawPoint(canvas,"E",mE,Color.YELLOW,posX,posY);
- posY = debugDrawPoint(canvas,"F",mF,Color.LTGRAY,posX,posY);
- posY = debugDrawPoint(canvas,"Mov",mMovement,Color.DKGRAY,posX,posY);
- posY = debugDrawPoint(canvas,"Origin",mOrigin,Color.MAGENTA,posX,posY);
- posY = debugDrawPoint(canvas,"Finger",mFinger,Color.GREEN,posX,posY);
- }
- private float debugDrawPoint(Canvas canvas, String name, Vector2D point, int color, float posX, float posY) {
- return debugDrawPoint(canvas,name+" "+point.toString(),point.x, point.y, color, posX, posY);
- }
- private float debugDrawPoint(Canvas canvas, String name, float X, float Y, int color, float posX, float posY) {
- mTextPaint.setColor(color);
- drawTextShadowed(canvas,name,posX , posY, mTextPaint,mTextPaintShadow);
- Paint paint = new Paint();
- paint.setStrokeWidth(5);
- paint.setColor(color);
- canvas.drawPoint(X, Y, paint);
- return posY+15;
- }
- }
'IT > Android' 카테고리의 다른 글
안드로이드 볼륨 변경 설정 (0) | 2012.08.01 |
---|---|
안드로이드 Frame Animation 실행하기(onCreate에서는 호출할 수 없을때) (0) | 2012.02.20 |
안드로이드 리스트뷰오른쪽에 빨리 이동할수있는 텀브넣기 (0) | 2012.02.16 |
안드로이드 버튼에 텍스트와 이미지 같이 출력하기 (0) | 2012.02.16 |
안드로이드 SharedPreferences 변화 감지하기 (0) | 2012.02.16 |