需求需要,做一個分數翻頁的效果,在網上找了很久,參照一個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