需求需要,做一个分数翻页的效果,在网上找了很久,参照一个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;
}
}
}
/**显示需要显示的数字
* @param canvas*/
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