天天看點

android 上下翻頁效果(FlipView)

需求需要,做一個分數翻頁的效果,在網上找了很久,參照一個github的項目,自己寫了個demo,現在記錄下思路

參考項目位址:https://github.com/emilsjolander/android-FlipView

實作步驟:

1.由Scroller類實作動畫,

mScroller.startScroll(startX,startY,dx,dy,duration);

通過移動距離和移動時間,由getCurrY()擷取目前距離

2.翻頁效果的繪制分為三部分(由第一步計算到的距離來不斷重新整理頁面)

-->繪制控件的上半部分 

canvas.clipRect(mTooRect);

-->繪制控件的下半部分 

canvas.clipRect(mBottomRect);

-->繪制中間翻頁部分 

camera.rotateX(),沿X軸翻轉

canvas.clipRect(mTooRect ormBottomRect),根據目前翻轉的度數(0~180度),決定畫布裁剪部分

camera.getMatrix(mMatrix),設定matrix矩陣的值,對中間頁進行變形,達到翻頁的視覺效果

positionMatrix()

canvas.concat(mMatrix);

drawChild(),繪制控件

關鍵代碼:

------------------

 @Override

    protectedvoid dispatchDraw(Canvas canvas) {

        super.dispatchDraw(canvas);

//如果Scroller開始滾動,則開始繪制頁面

        if(!mScroller.isFinished() && mScroller.computeScrollOffset()){

            drawTopHalf(canvas);

            drawBottomHalf(canvas);

            drawFlipHalf(canvas);

            postInvalidate();

        }else {//繪制完成之後,将需要顯示的頁面繪制出來

            if(isFlipping){

                showViews(canvas);

            }

            if(mScroller.isFinished() && !mScroller.computeScrollOffset()){

                isFlipping = false;

            }

}

    }

    privatevoid showViews(Canvas canvas) {

        String current = mVisibleTextView.getText().toString();

        String past = mInvisibleTextView.getText().toString();

        mVisibleTextView.setText(past);

        mInvisibleTextView.setText(current);

        //防止切換抖動

        drawChild(canvas,mVisibleTextView,0);

    }

    privatevoid drawBottomHalf(Canvas canvas) {

        canvas.save();

        canvas.clipRect(mBottomRect);

        View drawView = isUp ? mInvisibleTextView : mVisibleTextView;

        drawChild(canvas,drawView,0);

        canvas.restore();

    }

    privatevoid drawTopHalf(Canvas canvas) {

        canvas.save();

        canvas.clipRect(mTopRect);

        View drawView = isUp ? mVisibleTextView : mInvisibleTextView;

        drawChild(canvas,drawView,0);

        canvas.restore();

    }

    privatevoid drawFlipHalf(Canvas canvas) {

        canvas.save();

        mCamera.save();

        View view = null;

        float deg = getDeg();

        if(deg >90){

            canvas.clipRect(isUp ? mTopRect : mBottomRect);

            mCamera.rotateX(isUp ? deg - 180 : -(deg -180));

            view = mInvisibleTextView;

        }else {

            canvas.clipRect(isUp ? mBottomRect : mTopRect);

            mCamera.rotateX(isUp ? deg : -deg);

            view = mVisibleTextView ;

        }

        mCamera.getMatrix(mMatrix);

        positionMatrix();

        canvas.concat(mMatrix);

        if(view !=null){

            drawChild(canvas,view,0);

        }

        drawFlippingShadeShine(canvas);

        mCamera.restore();

        canvas.restore();

    }

    privatefloat getDeg() {

        return mScroller.getCurrY() *1.0f / layoutHeight * 180;

    }

    privatevoid drawFlippingShadeShine(Canvas canvas) {

        finalfloat degreesFlipped = getDeg();

        Log.d(TAG,"deg: " + degreesFlipped);

        if (degreesFlipped <90) {

            finalint alpha = getAlpha(degreesFlipped);

            Log.d(TAG,"小于90度時的透明度-------------------> " + alpha);

            mShinePaint.setAlpha(alpha);

            mShadePaint.setAlpha(alpha);

            canvas.drawRect(isUp ? mBottomRect : mTopRect, isUp ? mShinePaint : mShadePaint);

        } else {

            finalint alpha = getAlpha(Math.abs(degreesFlipped -180));

            Log.d(TAG,"大于90度時的透明度-------------> " + alpha);

            mShadePaint.setAlpha(alpha);

            mShinePaint.setAlpha(alpha);

            canvas.drawRect(isUp ? mTopRect : mBottomRect, isUp ? mShadePaint : mShinePaint);

        }

    }

demo下載下傳位址:

http://download.csdn.net/detail/beikin/9565370