<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    posts - 495,comments - 227,trackbacks - 0


    package sf.hmg.turntest;

    import android.content.Context;
    import android.graphics.Bitmap;
    import android.graphics.Canvas;
    import android.graphics.ColorMatrix;
    import android.graphics.ColorMatrixColorFilter;
    import android.graphics.Matrix;
    import android.graphics.Paint;
    import android.graphics.Path;
    import android.graphics.PointF;
    import android.graphics.Region;
    import android.graphics.drawable.GradientDrawable;
    import android.view.MotionEvent;
    import android.view.View;
    import android.widget.Scroller;

    public class PageWidget extends View {

        
    private static final String TAG = "hmg";
        
    private int mWidth = 480;
        
    private int mHeight = 800;
        
    private int mCornerX = 0// 拖拽點對應(yīng)的頁腳
        private int mCornerY = 0;
        
    private Path mPath0;
        
    private Path mPath1;
        Bitmap mCurPageBitmap 
    = null// 當(dāng)前頁
        Bitmap mNextPageBitmap = null;

        PointF mTouch 
    = new PointF(); // 拖拽點
        PointF mBezierStart1 = new PointF(); // 貝塞爾曲線起始點
        PointF mBezierControl1 = new PointF(); // 貝塞爾曲線控制點
        PointF mBeziervertex1 = new PointF(); // 貝塞爾曲線頂點
        PointF mBezierEnd1 = new PointF(); // 貝塞爾曲線結(jié)束點

        PointF mBezierStart2 
    = new PointF(); // 另一條貝塞爾曲線
        PointF mBezierControl2 = new PointF();
        PointF mBeziervertex2 
    = new PointF();
        PointF mBezierEnd2 
    = new PointF();

        
    float mMiddleX;
        
    float mMiddleY;
        
    float mDegrees;
        
    float mTouchToCornerDis;
        ColorMatrixColorFilter mColorMatrixFilter;
        Matrix mMatrix;
        
    float[] mMatrixArray = { 000000001.0f };

        
    boolean mIsRTandLB; // 是否屬于右上左下
        float mMaxLength = (float) Math.hypot(mWidth, mHeight);
        
    int[] mBackShadowColors;
        
    int[] mFrontShadowColors;
        GradientDrawable mBackShadowDrawableLR;
        GradientDrawable mBackShadowDrawableRL;
        GradientDrawable mFolderShadowDrawableLR;
        GradientDrawable mFolderShadowDrawableRL;

        GradientDrawable mFrontShadowDrawableHBT;
        GradientDrawable mFrontShadowDrawableHTB;
        GradientDrawable mFrontShadowDrawableVLR;
        GradientDrawable mFrontShadowDrawableVRL;

        Paint mPaint;

        Scroller mScroller;

        
    public PageWidget(Context context) {
            
    super(context);
            
    // TODO Auto-generated constructor stub
            mPath0 = new Path();
            mPath1 
    = new Path();
            createDrawable();

            mPaint 
    = new Paint();
            mPaint.setStyle(Paint.Style.FILL);

            ColorMatrix cm 
    = new ColorMatrix();
            
    float array[] = { 0.55f00080.0f00.55f0080.0f00,
                    
    0.55f080.0f0000.2f0 };
            cm.set(array);
            mColorMatrixFilter 
    = new ColorMatrixColorFilter(cm);
            mMatrix 
    = new Matrix();
            mScroller 
    = new Scroller(getContext());

            mTouch.x 
    = 0.01f// 不讓x,y為0,否則在點計算時會有問題
            mTouch.y = 0.01f;
        }

        
    /**
         * Author : hmg25 Version: 1.0 Description : 計算拖拽點對應(yīng)的拖拽腳
         
    */
        
    public void calcCornerXY(float x, float y) {
            
    if (x <= mWidth / 2)
                mCornerX 
    = 0;
            
    else
                mCornerX 
    = mWidth;
            
    if (y <= mHeight / 2)
                mCornerY 
    = 0;
            
    else
                mCornerY 
    = mHeight;
            
    if ((mCornerX == 0 && mCornerY == mHeight)
                    
    || (mCornerX == mWidth && mCornerY == 0))
                mIsRTandLB 
    = true;
            
    else
                mIsRTandLB 
    = false;
        }

        
    public boolean doTouchEvent(MotionEvent event) {
            
    // TODO Auto-generated method stub
            if (event.getAction() == MotionEvent.ACTION_MOVE) {
                mTouch.x 
    = event.getX();
                mTouch.y 
    = event.getY();
                
    this.postInvalidate();
            }
            
    if (event.getAction() == MotionEvent.ACTION_DOWN) {
                mTouch.x 
    = event.getX();
                mTouch.y 
    = event.getY();
                
    // calcCornerXY(mTouch.x, mTouch.y);
                
    // this.postInvalidate();
            }
            
    if (event.getAction() == MotionEvent.ACTION_UP) {
                
    if (canDragOver()) {
                    startAnimation(
    1200);
                } 
    else {
                    mTouch.x 
    = mCornerX - 0.09f;
                    mTouch.y 
    = mCornerY - 0.09f;
                }

                
    this.postInvalidate();
            }
            
    // return super.onTouchEvent(event);
            return true;
        }

        
    /**
         * Author : hmg25 Version: 1.0 Description : 求解直線P1P2和直線P3P4的交點坐標(biāo)
         
    */
        
    public PointF getCross(PointF P1, PointF P2, PointF P3, PointF P4) {
            PointF CrossP 
    = new PointF();
            
    // 二元函數(shù)通式: y=ax+b
            float a1 = (P2.y - P1.y) / (P2.x - P1.x);
            
    float b1 = ((P1.x * P2.y) - (P2.x * P1.y)) / (P1.x - P2.x);

            
    float a2 = (P4.y - P3.y) / (P4.x - P3.x);
            
    float b2 = ((P3.x * P4.y) - (P4.x * P3.y)) / (P3.x - P4.x);
            CrossP.x 
    = (b2 - b1) / (a1 - a2);
            CrossP.y 
    = a1 * CrossP.x + b1;
            
    return CrossP;
        }

        
    private void calcPoints() {
            mMiddleX 
    = (mTouch.x + mCornerX) / 2;
            mMiddleY 
    = (mTouch.y + mCornerY) / 2;
            mBezierControl1.x 
    = mMiddleX - (mCornerY - mMiddleY)
                    
    * (mCornerY - mMiddleY) / (mCornerX - mMiddleX);
            mBezierControl1.y 
    = mCornerY;
            mBezierControl2.x 
    = mCornerX;
            mBezierControl2.y 
    = mMiddleY - (mCornerX - mMiddleX)
                    
    * (mCornerX - mMiddleX) / (mCornerY - mMiddleY);

            
    // Log.i("hmg", "mTouchX  " + mTouch.x + "  mTouchY  " + mTouch.y);
            
    // Log.i("hmg", "mBezierControl1.x  " + mBezierControl1.x
            
    // + "  mBezierControl1.y  " + mBezierControl1.y);
            
    // Log.i("hmg", "mBezierControl2.x  " + mBezierControl2.x
            
    // + "  mBezierControl2.y  " + mBezierControl2.y);

            mBezierStart1.x 
    = mBezierControl1.x - (mCornerX - mBezierControl1.x)
                    
    / 2;
            mBezierStart1.y 
    = mCornerY;

            
    // 當(dāng)mBezierStart1.x < 0或者mBezierStart1.x > 480時
            
    // 如果繼續(xù)翻頁,會出現(xiàn)BUG故在此限制
            if (mTouch.x > 0 && mTouch.x < mWidth) {
                
    if (mBezierStart1.x < 0 || mBezierStart1.x > mWidth) {
                    
    if (mBezierStart1.x < 0)
                        mBezierStart1.x 
    = mWidth - mBezierStart1.x;

                    
    float f1 = Math.abs(mCornerX - mTouch.x);
                    
    float f2 = mWidth * f1 / mBezierStart1.x;
                    mTouch.x 
    = Math.abs(mCornerX - f2);

                    
    float f3 = Math.abs(mCornerX - mTouch.x)
                            
    * Math.abs(mCornerY - mTouch.y) / f1;
                    mTouch.y 
    = Math.abs(mCornerY - f3);

                    mMiddleX 
    = (mTouch.x + mCornerX) / 2;
                    mMiddleY 
    = (mTouch.y + mCornerY) / 2;

                    mBezierControl1.x 
    = mMiddleX - (mCornerY - mMiddleY)
                            
    * (mCornerY - mMiddleY) / (mCornerX - mMiddleX);
                    mBezierControl1.y 
    = mCornerY;

                    mBezierControl2.x 
    = mCornerX;
                    mBezierControl2.y 
    = mMiddleY - (mCornerX - mMiddleX)
                            
    * (mCornerX - mMiddleX) / (mCornerY - mMiddleY);
                    
    // Log.i("hmg", "mTouchX --> " + mTouch.x + "  mTouchY-->  "
                    
    // + mTouch.y);
                    
    // Log.i("hmg", "mBezierControl1.x--  " + mBezierControl1.x
                    
    // + "  mBezierControl1.y -- " + mBezierControl1.y);
                    
    // Log.i("hmg", "mBezierControl2.x -- " + mBezierControl2.x
                    
    // + "  mBezierControl2.y -- " + mBezierControl2.y);
                    mBezierStart1.x = mBezierControl1.x
                            
    - (mCornerX - mBezierControl1.x) / 2;
                }
            }
            mBezierStart2.x 
    = mCornerX;
            mBezierStart2.y 
    = mBezierControl2.y - (mCornerY - mBezierControl2.y)
                    
    / 2;

            mTouchToCornerDis 
    = (float) Math.hypot((mTouch.x - mCornerX),
                    (mTouch.y 
    - mCornerY));

            mBezierEnd1 
    = getCross(mTouch, mBezierControl1, mBezierStart1,
                    mBezierStart2);
            mBezierEnd2 
    = getCross(mTouch, mBezierControl2, mBezierStart1,
                    mBezierStart2);

            
    // Log.i("hmg", "mBezierEnd1.x  " + mBezierEnd1.x + "  mBezierEnd1.y  "
            
    // + mBezierEnd1.y);
            
    // Log.i("hmg", "mBezierEnd2.x  " + mBezierEnd2.x + "  mBezierEnd2.y  "
            
    // + mBezierEnd2.y);

            
    /*
             * mBeziervertex1.x 推導(dǎo)
             * ((mBezierStart1.x+mBezierEnd1.x)/2+mBezierControl1.x)/2 化簡等價于
             * (mBezierStart1.x+ 2*mBezierControl1.x+mBezierEnd1.x) / 4
             
    */
            mBeziervertex1.x 
    = (mBezierStart1.x + 2 * mBezierControl1.x + mBezierEnd1.x) / 4;
            mBeziervertex1.y 
    = (2 * mBezierControl1.y + mBezierStart1.y + mBezierEnd1.y) / 4;
            mBeziervertex2.x 
    = (mBezierStart2.x + 2 * mBezierControl2.x + mBezierEnd2.x) / 4;
            mBeziervertex2.y 
    = (2 * mBezierControl2.y + mBezierStart2.y + mBezierEnd2.y) / 4;
        }

        
    private void drawCurrentPageArea(Canvas canvas, Bitmap bitmap, Path path) {
            mPath0.reset();
            mPath0.moveTo(mBezierStart1.x, mBezierStart1.y);
            mPath0.quadTo(mBezierControl1.x, mBezierControl1.y, mBezierEnd1.x,
                    mBezierEnd1.y);
            mPath0.lineTo(mTouch.x, mTouch.y);
            mPath0.lineTo(mBezierEnd2.x, mBezierEnd2.y);
            mPath0.quadTo(mBezierControl2.x, mBezierControl2.y, mBezierStart2.x,
                    mBezierStart2.y);
            mPath0.lineTo(mCornerX, mCornerY);
            mPath0.close();

            canvas.save();
            canvas.clipPath(path, Region.Op.XOR);
            canvas.drawBitmap(bitmap, 
    00null);
            canvas.restore();
        }

        
    private void drawNextPageAreaAndShadow(Canvas canvas, Bitmap bitmap) {
            mPath1.reset();
            mPath1.moveTo(mBezierStart1.x, mBezierStart1.y);
            mPath1.lineTo(mBeziervertex1.x, mBeziervertex1.y);
            mPath1.lineTo(mBeziervertex2.x, mBeziervertex2.y);
            mPath1.lineTo(mBezierStart2.x, mBezierStart2.y);
            mPath1.lineTo(mCornerX, mCornerY);
            mPath1.close();

            mDegrees 
    = (float) Math.toDegrees(Math.atan2(mBezierControl1.x
                    
    - mCornerX, mBezierControl2.y - mCornerY));
            
    int leftx;
            
    int rightx;
            GradientDrawable mBackShadowDrawable;
            
    if (mIsRTandLB) {
                leftx 
    = (int) (mBezierStart1.x);
                rightx 
    = (int) (mBezierStart1.x + mTouchToCornerDis / 4);
                mBackShadowDrawable 
    = mBackShadowDrawableLR;
            } 
    else {
                leftx 
    = (int) (mBezierStart1.x - mTouchToCornerDis / 4);
                rightx 
    = (int) mBezierStart1.x;
                mBackShadowDrawable 
    = mBackShadowDrawableRL;
            }
            canvas.save();
            canvas.clipPath(mPath0);
            canvas.clipPath(mPath1, Region.Op.INTERSECT);
            canvas.drawBitmap(bitmap, 
    00null);
            canvas.rotate(mDegrees, mBezierStart1.x, mBezierStart1.y);
            mBackShadowDrawable.setBounds(leftx, (
    int) mBezierStart1.y, rightx,
                    (
    int) (mMaxLength + mBezierStart1.y));
            mBackShadowDrawable.draw(canvas);
            canvas.restore();
        }

        
    public void setBitmaps(Bitmap bm1, Bitmap bm2) {
            mCurPageBitmap 
    = bm1;
            mNextPageBitmap 
    = bm2;
        }

        
    public void setScreen(int w, int h) {
            mWidth 
    = w;
            mHeight 
    = h;
        }

        @Override
        
    protected void onDraw(Canvas canvas) {
            canvas.drawColor(
    0xFFAAAAAA);
            calcPoints();
            drawCurrentPageArea(canvas, mCurPageBitmap, mPath0);
            drawNextPageAreaAndShadow(canvas, mNextPageBitmap);
            drawCurrentPageShadow(canvas);
            drawCurrentBackArea(canvas, mCurPageBitmap);
        }

        
    /**
         * Author : hmg25 Version: 1.0 Description : 創(chuàng)建陰影的GradientDrawable
         
    */
        
    private void createDrawable() {
            
    int[] color = { 0x3333330xb0333333 };
            mFolderShadowDrawableRL 
    = new GradientDrawable(
                    GradientDrawable.Orientation.RIGHT_LEFT, color);
            mFolderShadowDrawableRL
                    .setGradientType(GradientDrawable.LINEAR_GRADIENT);

            mFolderShadowDrawableLR 
    = new GradientDrawable(
                    GradientDrawable.Orientation.LEFT_RIGHT, color);
            mFolderShadowDrawableLR
                    .setGradientType(GradientDrawable.LINEAR_GRADIENT);

            mBackShadowColors 
    = new int[] { 0xff1111110x111111 };
            mBackShadowDrawableRL 
    = new GradientDrawable(
                    GradientDrawable.Orientation.RIGHT_LEFT, mBackShadowColors);
            mBackShadowDrawableRL.setGradientType(GradientDrawable.LINEAR_GRADIENT);

            mBackShadowDrawableLR 
    = new GradientDrawable(
                    GradientDrawable.Orientation.LEFT_RIGHT, mBackShadowColors);
            mBackShadowDrawableLR.setGradientType(GradientDrawable.LINEAR_GRADIENT);

            mFrontShadowColors 
    = new int[] { 0x801111110x111111 };
            mFrontShadowDrawableVLR 
    = new GradientDrawable(
                    GradientDrawable.Orientation.LEFT_RIGHT, mFrontShadowColors);
            mFrontShadowDrawableVLR
                    .setGradientType(GradientDrawable.LINEAR_GRADIENT);
            mFrontShadowDrawableVRL 
    = new GradientDrawable(
                    GradientDrawable.Orientation.RIGHT_LEFT, mFrontShadowColors);
            mFrontShadowDrawableVRL
                    .setGradientType(GradientDrawable.LINEAR_GRADIENT);

            mFrontShadowDrawableHTB 
    = new GradientDrawable(
                    GradientDrawable.Orientation.TOP_BOTTOM, mFrontShadowColors);
            mFrontShadowDrawableHTB
                    .setGradientType(GradientDrawable.LINEAR_GRADIENT);

            mFrontShadowDrawableHBT 
    = new GradientDrawable(
                    GradientDrawable.Orientation.BOTTOM_TOP, mFrontShadowColors);
            mFrontShadowDrawableHBT
                    .setGradientType(GradientDrawable.LINEAR_GRADIENT);
        }

        
    /**
         * Author : hmg25 Version: 1.0 Description : 繪制翻起頁的陰影
         
    */
        
    public void drawCurrentPageShadow(Canvas canvas) {
            
    double degree;
            
    if (mIsRTandLB) {
                degree 
    = Math.PI
                        
    / 4
                        
    - Math.atan2(mBezierControl1.y - mTouch.y, mTouch.x
                                
    - mBezierControl1.x);
            } 
    else {
                degree 
    = Math.PI
                        
    / 4
                        
    - Math.atan2(mTouch.y - mBezierControl1.y, mTouch.x
                                
    - mBezierControl1.x);
            }
            
    // 翻起頁陰影頂點與touch點的距離
            double d1 = (float25 * 1.414 * Math.cos(degree);
            
    double d2 = (float25 * 1.414 * Math.sin(degree);
            
    float x = (float) (mTouch.x + d1);
            
    float y;
            
    if (mIsRTandLB) {
                y 
    = (float) (mTouch.y + d2);
            } 
    else {
                y 
    = (float) (mTouch.y - d2);
            }
            mPath1.reset();
            mPath1.moveTo(x, y);
            mPath1.lineTo(mTouch.x, mTouch.y);
            mPath1.lineTo(mBezierControl1.x, mBezierControl1.y);
            mPath1.lineTo(mBezierStart1.x, mBezierStart1.y);
            mPath1.close();
            
    float rotateDegrees;
            canvas.save();

            canvas.clipPath(mPath0, Region.Op.XOR);
            canvas.clipPath(mPath1, Region.Op.INTERSECT);
            
    int leftx;
            
    int rightx;
            GradientDrawable mCurrentPageShadow;
            
    if (mIsRTandLB) {
                leftx 
    = (int) (mBezierControl1.x);
                rightx 
    = (int) mBezierControl1.x + 25;
                mCurrentPageShadow 
    = mFrontShadowDrawableVLR;
            } 
    else {
                leftx 
    = (int) (mBezierControl1.x - 25);
                rightx 
    = (int) mBezierControl1.x + 1;
                mCurrentPageShadow 
    = mFrontShadowDrawableVRL;
            }

            rotateDegrees 
    = (float) Math.toDegrees(Math.atan2(mTouch.x
                    
    - mBezierControl1.x, mBezierControl1.y - mTouch.y));
            canvas.rotate(rotateDegrees, mBezierControl1.x, mBezierControl1.y);
            mCurrentPageShadow.setBounds(leftx,
                    (
    int) (mBezierControl1.y - mMaxLength), rightx,
                    (
    int) (mBezierControl1.y));
            mCurrentPageShadow.draw(canvas);
            canvas.restore();

            mPath1.reset();
            mPath1.moveTo(x, y);
            mPath1.lineTo(mTouch.x, mTouch.y);
            mPath1.lineTo(mBezierControl2.x, mBezierControl2.y);
            mPath1.lineTo(mBezierStart2.x, mBezierStart2.y);
            mPath1.close();
            canvas.save();
            canvas.clipPath(mPath0, Region.Op.XOR);
            canvas.clipPath(mPath1, Region.Op.INTERSECT);
            
    if (mIsRTandLB) {
                leftx 
    = (int) (mBezierControl2.y);
                rightx 
    = (int) (mBezierControl2.y + 25);
                mCurrentPageShadow 
    = mFrontShadowDrawableHTB;
            } 
    else {
                leftx 
    = (int) (mBezierControl2.y - 25);
                rightx 
    = (int) (mBezierControl2.y + 1);
                mCurrentPageShadow 
    = mFrontShadowDrawableHBT;
            }
            rotateDegrees 
    = (float) Math.toDegrees(Math.atan2(mBezierControl2.y
                    
    - mTouch.y, mBezierControl2.x - mTouch.x));
            canvas.rotate(rotateDegrees, mBezierControl2.x, mBezierControl2.y);
            
    float temp;
            
    if (mBezierControl2.y < 0)
                temp 
    = mBezierControl2.y - mHeight;
            
    else
                temp 
    = mBezierControl2.y;

            
    int hmg = (int) Math.hypot(mBezierControl2.x, temp);
            
    if (hmg > mMaxLength)
                mCurrentPageShadow
                        .setBounds((
    int) (mBezierControl2.x - 25- hmg, leftx,
                                (
    int) (mBezierControl2.x + mMaxLength) - hmg,
                                rightx);
            
    else
                mCurrentPageShadow.setBounds(
                        (
    int) (mBezierControl2.x - mMaxLength), leftx,
                        (
    int) (mBezierControl2.x), rightx);

            
    // Log.i("hmg", "mBezierControl2.x   " + mBezierControl2.x
            
    // + "  mBezierControl2.y  " + mBezierControl2.y);
            mCurrentPageShadow.draw(canvas);
            canvas.restore();
        }

        
    /**
         * Author : hmg25 Version: 1.0 Description : 繪制翻起頁背面
         
    */
        
    private void drawCurrentBackArea(Canvas canvas, Bitmap bitmap) {
            
    int i = (int) (mBezierStart1.x + mBezierControl1.x) / 2;
            
    float f1 = Math.abs(i - mBezierControl1.x);
            
    int i1 = (int) (mBezierStart2.y + mBezierControl2.y) / 2;
            
    float f2 = Math.abs(i1 - mBezierControl2.y);
            
    float f3 = Math.min(f1, f2);
            mPath1.reset();
            mPath1.moveTo(mBeziervertex2.x, mBeziervertex2.y);
            mPath1.lineTo(mBeziervertex1.x, mBeziervertex1.y);
            mPath1.lineTo(mBezierEnd1.x, mBezierEnd1.y);
            mPath1.lineTo(mTouch.x, mTouch.y);
            mPath1.lineTo(mBezierEnd2.x, mBezierEnd2.y);
            mPath1.close();
            GradientDrawable mFolderShadowDrawable;
            
    int left;
            
    int right;
            
    if (mIsRTandLB) {
                left 
    = (int) (mBezierStart1.x - 1);
                right 
    = (int) (mBezierStart1.x + f3 + 1);
                mFolderShadowDrawable 
    = mFolderShadowDrawableLR;
            } 
    else {
                left 
    = (int) (mBezierStart1.x - f3 - 1);
                right 
    = (int) (mBezierStart1.x + 1);
                mFolderShadowDrawable 
    = mFolderShadowDrawableRL;
            }
            canvas.save();
            canvas.clipPath(mPath0);
            canvas.clipPath(mPath1, Region.Op.INTERSECT);

            mPaint.setColorFilter(mColorMatrixFilter);

            
    float dis = (float) Math.hypot(mCornerX - mBezierControl1.x,
                    mBezierControl2.y 
    - mCornerY);
            
    float f8 = (mCornerX - mBezierControl1.x) / dis;
            
    float f9 = (mBezierControl2.y - mCornerY) / dis;
            mMatrixArray[
    0= 1 - 2 * f9 * f9;
            mMatrixArray[
    1= 2 * f8 * f9;
            mMatrixArray[
    3= mMatrixArray[1];
            mMatrixArray[
    4= 1 - 2 * f8 * f8;
            mMatrix.reset();
            mMatrix.setValues(mMatrixArray);
            mMatrix.preTranslate(
    -mBezierControl1.x, -mBezierControl1.y);
            mMatrix.postTranslate(mBezierControl1.x, mBezierControl1.y);
            canvas.drawBitmap(bitmap, mMatrix, mPaint);
            
    // canvas.drawBitmap(bitmap, mMatrix, null);
            mPaint.setColorFilter(null);
            canvas.rotate(mDegrees, mBezierStart1.x, mBezierStart1.y);
            mFolderShadowDrawable.setBounds(left, (
    int) mBezierStart1.y, right,
                    (
    int) (mBezierStart1.y + mMaxLength));
            mFolderShadowDrawable.draw(canvas);
            canvas.restore();
        }

        
    public void computeScroll() {
            
    super.computeScroll();
            
    if (mScroller.computeScrollOffset()) {
                
    float x = mScroller.getCurrX();
                
    float y = mScroller.getCurrY();
                mTouch.x 
    = x;
                mTouch.y 
    = y;
                postInvalidate();
            }
        }

        
    private void startAnimation(int delayMillis) {
            
    int dx, dy;
            
    // dx 水平方向滑動的距離,負(fù)值會使?jié)L動向左滾動
            
    // dy 垂直方向滑動的距離,負(fù)值會使?jié)L動向上滾動
            if (mCornerX > 0) {
                dx 
    = -(int) (mWidth + mTouch.x);
            } 
    else {
                dx 
    = (int) (mWidth - mTouch.x + mWidth);
            }
            
    if (mCornerY > 0) {
                dy 
    = (int) (mHeight - mTouch.y);
            } 
    else {
                dy 
    = (int) (1 - mTouch.y); // 防止mTouch.y最終變?yōu)?
            }
            mScroller.startScroll((
    int) mTouch.x, (int) mTouch.y, dx, dy,
                    delayMillis);
        }

        
    public void abortAnimation() {
            
    if (!mScroller.isFinished()) {
                mScroller.abortAnimation();
            }
        }

        
    public boolean canDragOver() {
            
    if (mTouchToCornerDis > mWidth / 10)
                
    return true;
            
    return false;
        }

        
    /**
         * Author : hmg25 Version: 1.0 Description : 是否從左邊翻向右邊
         
    */
        
    public boolean DragToRight() {
            
    if (mCornerX > 0)
                
    return false;
            
    return true;
        }

    }

    /**
     *  Author :  hmg25
     *  Description :
     
    */
    package sf.hmg.turntest;

    import java.io.File;
    import java.io.IOException;
    import java.io.RandomAccessFile;
    import java.io.UnsupportedEncodingException;
    import java.nio.MappedByteBuffer;
    import java.nio.channels.FileChannel;
    import java.text.DecimalFormat;
    import java.util.Vector;

    import android.graphics.Bitmap;
    import android.graphics.Canvas;
    import android.graphics.Color;
    import android.graphics.Paint;
    import android.graphics.Paint.Align;

    public class BookPageFactory {

        
    private File book_file = null;
        
    private MappedByteBuffer m_mbBuf = null;
        
    private int m_mbBufLen = 0;
        
    private int m_mbBufBegin = 0;
        
    private int m_mbBufEnd = 0;
        
    private String m_strCharsetName = "GBK";
        
    private Bitmap m_book_bg = null;
        
    private int mWidth;
        
    private int mHeight;

        
    private Vector<String> m_lines = new Vector<String>();

        
    private int m_fontSize = 24;
        
    private int m_textColor = Color.BLACK;
        
    private int m_backColor = 0xffff9e85// 背景顏色
        private int marginWidth = 15// 左右與邊緣的距離
        private int marginHeight = 20// 上下與邊緣的距離

        
    private int mLineCount; // 每頁可以顯示的行數(shù)
        private float mVisibleHeight; // 繪制內(nèi)容的寬
        private float mVisibleWidth; // 繪制內(nèi)容的寬
        private boolean m_isfirstPage,m_islastPage;

        
    // private int m_nLineSpaceing = 5;

        
    private Paint mPaint;

        
    public BookPageFactory(int w, int h) {
            
    // TODO Auto-generated constructor stub
            mWidth = w;
            mHeight 
    = h;
            mPaint 
    = new Paint(Paint.ANTI_ALIAS_FLAG);
            mPaint.setTextAlign(Align.LEFT);
            mPaint.setTextSize(m_fontSize);
            mPaint.setColor(m_textColor);
            mVisibleWidth 
    = mWidth - marginWidth * 2;
            mVisibleHeight 
    = mHeight - marginHeight * 2;
            mLineCount 
    = (int) (mVisibleHeight / m_fontSize); // 可顯示的行數(shù)
        }

        
    public void openbook(String strFilePath) throws IOException {
            book_file 
    = new File(strFilePath);
            
    long lLen = book_file.length();
            m_mbBufLen 
    = (int) lLen;
            m_mbBuf 
    = new RandomAccessFile(book_file, "r").getChannel().map(
                    FileChannel.MapMode.READ_ONLY, 
    0, lLen);
        }
        

        
    protected byte[] readParagraphBack(int nFromPos) {
            
    int nEnd = nFromPos;
            
    int i;
            
    byte b0, b1;
            
    if (m_strCharsetName.equals("UTF-16LE")) {
                i 
    = nEnd - 2;
                
    while (i > 0) {
                    b0 
    = m_mbBuf.get(i);
                    b1 
    = m_mbBuf.get(i + 1);
                    
    if (b0 == 0x0a && b1 == 0x00 && i != nEnd - 2) {
                        i 
    += 2;
                        
    break;
                    }
                    i
    --;
                }

            } 
    else if (m_strCharsetName.equals("UTF-16BE")) {
                i 
    = nEnd - 2;
                
    while (i > 0) {
                    b0 
    = m_mbBuf.get(i);
                    b1 
    = m_mbBuf.get(i + 1);
                    
    if (b0 == 0x00 && b1 == 0x0a && i != nEnd - 2) {
                        i 
    += 2;
                        
    break;
                    }
                    i
    --;
                }
            } 
    else {
                i 
    = nEnd - 1;
                
    while (i > 0) {
                    b0 
    = m_mbBuf.get(i);
                    
    if (b0 == 0x0a && i != nEnd - 1) {
                        i
    ++;
                        
    break;
                    }
                    i
    --;
                }
            }
            
    if (i < 0)
                i 
    = 0;
            
    int nParaSize = nEnd - i;
            
    int j;
            
    byte[] buf = new byte[nParaSize];
            
    for (j = 0; j < nParaSize; j++) {
                buf[j] 
    = m_mbBuf.get(i + j);
            }
            
    return buf;
        }


        
    // 讀取上一段落
        protected byte[] readParagraphForward(int nFromPos) {
            
    int nStart = nFromPos;
            
    int i = nStart;
            
    byte b0, b1;
            
    // 根據(jù)編碼格式判斷換行
            if (m_strCharsetName.equals("UTF-16LE")) {
                
    while (i < m_mbBufLen - 1) {
                    b0 
    = m_mbBuf.get(i++);
                    b1 
    = m_mbBuf.get(i++);
                    
    if (b0 == 0x0a && b1 == 0x00) {
                        
    break;
                    }
                }
            } 
    else if (m_strCharsetName.equals("UTF-16BE")) {
                
    while (i < m_mbBufLen - 1) {
                    b0 
    = m_mbBuf.get(i++);
                    b1 
    = m_mbBuf.get(i++);
                    
    if (b0 == 0x00 && b1 == 0x0a) {
                        
    break;
                    }
                }
            } 
    else {
                
    while (i < m_mbBufLen) {
                    b0 
    = m_mbBuf.get(i++);
                    
    if (b0 == 0x0a) {
                        
    break;
                    }
                }
            }
            
    int nParaSize = i - nStart;
            
    byte[] buf = new byte[nParaSize];
            
    for (i = 0; i < nParaSize; i++) {
                buf[i] 
    = m_mbBuf.get(nFromPos + i);
            }
            
    return buf;
        }

        
    protected Vector<String> pageDown() {
            String strParagraph 
    = "";
            Vector
    <String> lines = new Vector<String>();
            
    while (lines.size() < mLineCount && m_mbBufEnd < m_mbBufLen) {
                
    byte[] paraBuf = readParagraphForward(m_mbBufEnd); // 讀取一個段落
                m_mbBufEnd += paraBuf.length;
                
    try {
                    strParagraph 
    = new String(paraBuf, m_strCharsetName);
                } 
    catch (UnsupportedEncodingException e) {
                    
    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                String strReturn 
    = "";
                
    if (strParagraph.indexOf("\r\n"!= -1) {
                    strReturn 
    = "\r\n";
                    strParagraph 
    = strParagraph.replaceAll("\r\n""");
                } 
    else if (strParagraph.indexOf("\n"!= -1) {
                    strReturn 
    = "\n";
                    strParagraph 
    = strParagraph.replaceAll("\n""");
                }

                
    if (strParagraph.length() == 0) {
                    lines.add(strParagraph);
                }
                
    while (strParagraph.length() > 0) {
                    
    int nSize = mPaint.breakText(strParagraph, true, mVisibleWidth,
                            
    null);
                    lines.add(strParagraph.substring(
    0, nSize));
                    strParagraph 
    = strParagraph.substring(nSize);
                    
    if (lines.size() >= mLineCount) {
                        
    break;
                    }
                }
                
    if (strParagraph.length() != 0) {
                    
    try {
                        m_mbBufEnd 
    -= (strParagraph + strReturn)
                                .getBytes(m_strCharsetName).length;
                    } 
    catch (UnsupportedEncodingException e) {
                        
    // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
            }
            
    return lines;
        }

        
    protected void pageUp() {
            
    if (m_mbBufBegin < 0)
                m_mbBufBegin 
    = 0;
            Vector
    <String> lines = new Vector<String>();
            String strParagraph 
    = "";
            
    while (lines.size() < mLineCount && m_mbBufBegin > 0) {
                Vector
    <String> paraLines = new Vector<String>();
                
    byte[] paraBuf = readParagraphBack(m_mbBufBegin);
                m_mbBufBegin 
    -= paraBuf.length;
                
    try {
                    strParagraph 
    = new String(paraBuf, m_strCharsetName);
                } 
    catch (UnsupportedEncodingException e) {
                    
    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                strParagraph 
    = strParagraph.replaceAll("\r\n""");
                strParagraph 
    = strParagraph.replaceAll("\n""");

                
    if (strParagraph.length() == 0) {
                    paraLines.add(strParagraph);
                }
                
    while (strParagraph.length() > 0) {
                    
    int nSize = mPaint.breakText(strParagraph, true, mVisibleWidth,
                            
    null);
                    paraLines.add(strParagraph.substring(
    0, nSize));
                    strParagraph 
    = strParagraph.substring(nSize);
                }
                lines.addAll(
    0, paraLines);
            }
            
    while (lines.size() > mLineCount) {
                
    try {
                    m_mbBufBegin 
    += lines.get(0).getBytes(m_strCharsetName).length;
                    lines.remove(
    0);
                } 
    catch (UnsupportedEncodingException e) {
                    
    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
            m_mbBufEnd 
    = m_mbBufBegin;
            
    return;
        }

        
    protected void prePage() throws IOException {
            
    if (m_mbBufBegin <= 0) {
                m_mbBufBegin 
    = 0;
                m_isfirstPage
    =true;
                
    return;
            }
    else m_isfirstPage=false;
            m_lines.clear();
            pageUp();
            m_lines 
    = pageDown();
        }

        
    public void nextPage() throws IOException {
            
    if (m_mbBufEnd >= m_mbBufLen) {
                m_islastPage
    =true;
                
    return;
            }
    else m_islastPage=false;
            m_lines.clear();
            m_mbBufBegin 
    = m_mbBufEnd;
            m_lines 
    = pageDown();
        }

        
    public void onDraw(Canvas c) {
            
    if (m_lines.size() == 0)
                m_lines 
    = pageDown();
            
    if (m_lines.size() > 0) {
                
    if (m_book_bg == null)
                    c.drawColor(m_backColor);
                
    else
                    c.drawBitmap(m_book_bg, 
    00null);
                
    int y = marginHeight;
                
    for (String strLine : m_lines) {
                    y 
    += m_fontSize;
                    c.drawText(strLine, marginWidth, y, mPaint);
                }
            }
            
    float fPercent = (float) (m_mbBufBegin * 1.0 / m_mbBufLen);
            DecimalFormat df 
    = new DecimalFormat("#0.0");
            String strPercent 
    = df.format(fPercent * 100+ "%";
            
    int nPercentWidth = (int) mPaint.measureText("999.9%"+ 1;
            c.drawText(strPercent, mWidth 
    - nPercentWidth, mHeight - 5, mPaint);
        }

        
    public void setBgBitmap(Bitmap BG) {
            m_book_bg 
    = BG;
        }
        
        
    public boolean isfirstPage() {
            
    return m_isfirstPage;
        }
        
    public boolean islastPage() {
            
    return m_islastPage;
        }
    }

    package sf.hmg.turntest;

    import java.io.IOException;

    import android.app.Activity;
    import android.graphics.Bitmap;
    import android.graphics.BitmapFactory;
    import android.graphics.Canvas;
    import android.graphics.Paint;
    import android.os.Bundle;
    import android.view.MotionEvent;
    import android.view.View;
    import android.view.View.OnTouchListener;
    import android.view.Window;
    import android.view.WindowManager;
    import android.widget.Toast;

    public class turntest extends Activity {
        
    /** Called when the activity is first created. */
        
    private PageWidget mPageWidget;
        Bitmap mCurPageBitmap, mNextPageBitmap;
        Canvas mCurPageCanvas, mNextPageCanvas;
        BookPageFactory pagefactory;

        @Override
        
    public void onCreate(Bundle savedInstanceState) {
            
    super.onCreate(savedInstanceState);
            requestWindowFeature(Window.FEATURE_NO_TITLE);
            getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
                    WindowManager.LayoutParams.FLAG_FULLSCREEN);
            mPageWidget 
    = new PageWidget(this);
            setContentView(mPageWidget);

            mCurPageBitmap 
    = Bitmap.createBitmap(480800, Bitmap.Config.ARGB_8888);
            mNextPageBitmap 
    = Bitmap
                    .createBitmap(
    480800, Bitmap.Config.ARGB_8888);

            mCurPageCanvas 
    = new Canvas(mCurPageBitmap);
            mNextPageCanvas 
    = new Canvas(mNextPageBitmap);
            pagefactory 
    = new BookPageFactory(480800);

            pagefactory.setBgBitmap(BitmapFactory.decodeResource(
                    
    this.getResources(), R.drawable.bg));

            
    try {
                pagefactory.openbook(
    "/sdcard/test.txt");
                pagefactory.onDraw(mCurPageCanvas);
            } 
    catch (IOException e1) {
                
    // TODO Auto-generated catch block
                e1.printStackTrace();
                Toast.makeText(
    this"電子書不存在,請將《test.txt》放在SD卡根目錄下",
                        Toast.LENGTH_SHORT).show();
            }

            mPageWidget.setBitmaps(mCurPageBitmap, mCurPageBitmap);

            mPageWidget.setOnTouchListener(
    new OnTouchListener() {
                @Override
                
    public boolean onTouch(View v, MotionEvent e) {
                    
    // TODO Auto-generated method stub
                    
                    
    boolean ret=false;
                    
    if (v == mPageWidget) {
                        
    if (e.getAction() == MotionEvent.ACTION_DOWN) {
                            mPageWidget.abortAnimation();
                            mPageWidget.calcCornerXY(e.getX(), e.getY());

                            pagefactory.onDraw(mCurPageCanvas);
                            
    if (mPageWidget.DragToRight()) {
                                
    try {
                                    pagefactory.prePage();
                                } 
    catch (IOException e1) {
                                    
    // TODO Auto-generated catch block
                                    e1.printStackTrace();
                                }                        
                                
    if(pagefactory.isfirstPage())return false;
                                pagefactory.onDraw(mNextPageCanvas);
                            } 
    else {
                                
    try {
                                    pagefactory.nextPage();
                                } 
    catch (IOException e1) {
                                    
    // TODO Auto-generated catch block
                                    e1.printStackTrace();
                                }
                                
    if(pagefactory.islastPage())return false;
                                pagefactory.onDraw(mNextPageCanvas);
                            }
                            mPageWidget.setBitmaps(mCurPageBitmap, mNextPageBitmap);
                        }
                     
                         ret 
    = mPageWidget.doTouchEvent(e);
                        
    return ret;
                    }
                    
    return false;
                }

            });
        }
    }
    posted on 2011-09-21 11:59 SIMONE 閱讀(11108) 評論(2)  編輯  收藏 所屬分類: android

    FeedBack:
    # re: android酷炫翻頁效果+圖形分析
    2011-11-19 15:19 | veallytong
    轉(zhuǎn)人家的有什么意思?  回復(fù)  更多評論
      
    # re: android酷炫翻頁效果+圖形分析[未登錄]
    2015-04-21 14:58 | 123
    @veallytong
    看不出來你自己的分析在哪里。。。。。。。。  回復(fù)  更多評論
      
    主站蜘蛛池模板: 亚洲午夜久久久久久尤物| 国产亚洲精品a在线观看| 亚洲成AV人片一区二区密柚| 亚洲成av人在线观看网站| 一色屋成人免费精品网站| 亚洲男人都懂得羞羞网站| 国产精品永久免费| 国产精品亚洲mnbav网站| 亚洲精品日韩一区二区小说| 亚洲中文字幕乱码熟女在线| 国产成人免费ā片在线观看老同学| 免费的一级片网站| 国产精品亚洲专区无码唯爱网| 嫩草影院在线免费观看| 国产人成亚洲第一网站在线播放| 黄页网站在线看免费| 涩涩色中文综合亚洲| 成人午夜免费福利| 亚洲无码一区二区三区| 在线不卡免费视频| 一级人做人a爰免费视频| 国产精品亚洲片在线| 精品熟女少妇av免费久久| 亚洲国产模特在线播放| 日本免费人成黄页在线观看视频| 久久人午夜亚洲精品无码区| 亚洲Aⅴ无码一区二区二三区软件 亚洲AⅤ视频一区二区三区 | 亚洲成在人天堂一区二区| 亚洲区日韩区无码区| 中文字幕不卡高清免费| 亚洲国产综合第一精品小说| 韩国欧洲一级毛片免费| 中国一级毛片免费看视频| 亚洲视频在线观看网址| 美女被免费视频网站a国产| yellow视频免费在线观看| 亚洲av永久无码嘿嘿嘿| 国产综合精品久久亚洲| 嫖丰满老熟妇AAAA片免费看| 免费看黄福利app导航看一下黄色录像| 亚洲欧洲无码AV电影在线观看|