在一个recyclerView上实现item的立体翻转动画,魅族、小米、华为平板都试过了没问题,但是在一个7.0的华为手机上,只要一翻转item就消失了,网上发现也有其他人遇到这种问题,大概是objectAnimation的原因,于是只能尝试了用其他动画效果实现。
原先的方式是
private void animateStart(RecyclerView.ViewHolder holder) {
L.e(TAG, "animateStart、、、");
final MyViewHolder viewHolder = (MyViewHolder) holder;
// 获取需要被执行动画的View视图对象
LinearLayout newContainer = viewHolder.container; // 从mAnimatorMap缓存中查找当前newHolder对应的itemView动画是否在执行中,如果是则终止动画
AnimatorInfo runningInfo = mAnimatorMap.get(holder);
long prevAnimPlayTime = ;
boolean firstHalf = false;
if (runningInfo != null) {
firstHalf = runningInfo.oldTextRotator != null &&
runningInfo.oldTextRotator.isRunning();
prevAnimPlayTime = firstHalf ?
runningInfo.oldTextRotator.getCurrentPlayTime() :
runningInfo.newTextRotator.getCurrentPlayTime();
runningInfo.overallAnim.cancel();
}
// 初始化背景颜色渐变的属性动画
ObjectAnimator fadeToBlack = null, fadeFromBlack;
if (runningInfo == null || firstHalf) {
int startColor = Color.WHITE;
if (runningInfo != null) {
startColor = (Integer) runningInfo.fadeToBlackAnim.getAnimatedValue();
}
fadeToBlack = ObjectAnimator.ofInt(newContainer, "backgroundColor",
startColor, Color.WHITE);
fadeToBlack.setEvaluator(mColorEvaluator);
if (runningInfo != null) {
fadeToBlack.setCurrentPlayTime(prevAnimPlayTime);
}
} fadeFromBlack = ObjectAnimator.ofInt(newContainer, "backgroundColor",
Color.WHITE, Color.WHITE);
fadeFromBlack.setEvaluator(mColorEvaluator);
if (runningInfo != null && !firstHalf) {
fadeFromBlack.setCurrentPlayTime(prevAnimPlayTime);
} //背景动画
AnimatorSet bgAnim = new AnimatorSet();
if (fadeToBlack != null) {
bgAnim.playSequentially(fadeToBlack, fadeFromBlack);
} else {
bgAnim.play(fadeFromBlack);
}
// 初始化旋转的属性动画
ObjectAnimator oldTextRotate = null, newTextRotate;
if (runningInfo == null || firstHalf) {
oldTextRotate = ObjectAnimator.ofFloat(newContainer, View.ROTATION_X, , );
oldTextRotate.setInterpolator(mAccelerateInterpolator);
if (runningInfo != null) {
oldTextRotate.setCurrentPlayTime(prevAnimPlayTime);
} else {
L.e(TAG, "runningInfo == null 444444");
} } else {
L.e(TAG, "runningInfo == null && firstHalf 333333");
}
AnimatorSet textAnim = new AnimatorSet();
if (oldTextRotate != null) {
textAnim.playSequentially(oldTextRotate);
} else {
L.e(TAG, "oldTextRotate != null");
} final RecyclerView.ViewHolder newHolder = holder;
AnimatorSet changeAnim = new AnimatorSet();
changeAnim.playTogether(bgAnim, textAnim);
changeAnim.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
dispatchAnimationFinished(newHolder);
mAnimatorMap.remove(newHolder);
}
});
changeAnim.start();
}
后修改了翻转动画的objectAnimation的方法为:
private void animateStart(RecyclerView.ViewHolder holder) {
L.e(TAG, "animateStart、、、");
final MyViewHolder viewHolder = (MyViewHolder) holder;
// 获取需要被执行动画的View视图对象
LinearLayout newContainer = viewHolder.container; // 从mAnimatorMap缓存中查找当前newHolder对应的itemView动画是否在执行中,如果是则终止动画
AnimatorInfo runningInfo = mAnimatorMap.get(holder);
long prevAnimPlayTime = ;
boolean firstHalf = false;
if (runningInfo != null) {
firstHalf = runningInfo.oldTextRotator != null &&
runningInfo.oldTextRotator.isRunning();
prevAnimPlayTime = firstHalf ?
runningInfo.oldTextRotator.getCurrentPlayTime() :
runningInfo.newTextRotator.getCurrentPlayTime();
runningInfo.overallAnim.cancel();
}
// 初始化背景颜色渐变的属性动画
ObjectAnimator fadeToBlack = null, fadeFromBlack;
if (runningInfo == null || firstHalf) {
int startColor = Color.WHITE;
if (runningInfo != null) {
startColor = (Integer) runningInfo.fadeToBlackAnim.getAnimatedValue();
}
fadeToBlack = ObjectAnimator.ofInt(newContainer, "backgroundColor",
startColor, Color.WHITE);
fadeToBlack.setEvaluator(mColorEvaluator);
if (runningInfo != null) {
fadeToBlack.setCurrentPlayTime(prevAnimPlayTime);
}
} fadeFromBlack = ObjectAnimator.ofInt(newContainer, "backgroundColor",
Color.WHITE, Color.WHITE);
fadeFromBlack.setEvaluator(mColorEvaluator);
if (runningInfo != null && !firstHalf) {
fadeFromBlack.setCurrentPlayTime(prevAnimPlayTime);
} //背景动画
AnimatorSet bgAnim = new AnimatorSet();
if (fadeToBlack != null) {
bgAnim.playSequentially(fadeToBlack, fadeFromBlack);
} else {
bgAnim.play(fadeFromBlack);
}
startRotation(newContainer, , ); final RecyclerView.ViewHolder newHolder = holder;
AnimatorSet changeAnim = new AnimatorSet();
changeAnim.playTogether(bgAnim, textAnim);
changeAnim.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
dispatchAnimationFinished(newHolder);
mAnimatorMap.remove(newHolder);
}
});
changeAnim.start();
} private void startRotation(LinearLayout view,float start, float end) {
// 计算中心点
final float centerX = view.getWidth() / 2.0f;
final float centerY = view.getHeight() / 2.0f;
L.d(TAG, "centerX="+centerX+", centerY="+centerY);
// Create a new 3D rotation with the supplied parameter
// The animation listener is used to trigger the next animation
//final Rotate3dAnimation rotation =new Rotate3dAnimation(start, end, centerX, centerY, 310.0f, true);
//Z轴的缩放为0
Rotate3dAnimation rotation =new Rotate3dAnimation(start, end, centerX, centerY, 0f, true);
rotation.setDuration();
rotation.setFillAfter(true);
//rotation.setInterpolator(new AccelerateInterpolator());
//匀速旋转
rotation.setInterpolator(new LinearInterpolator());
//设置监听
StartNextRotate startNext = new StartNextRotate(rotation, view);
rotation.setAnimationListener(startNext);
view.startAnimation(rotation);
} private class StartNextRotate implements Animation.AnimationListener {
private Rotate3dAnimation rotation;
private LinearLayout view; public StartNextRotate(Rotate3dAnimation rotation, LinearLayout view){
this.rotation = rotation;
this.view = view;
}
public void onAnimationEnd(Animation animation) {
// TODO Auto-generated method stub
L.d(TAG, "onAnimationEnd......");
// view.startAnimation(rotation);//重复翻转
view.clearAnimation();
}
public void onAnimationRepeat(Animation animation) {
// TODO Auto-generated method stub
}
public void onAnimationStart(Animation animation) {
// TODO Auto-generated method stub
}
}
其中的Rotate3dAnimation是一个继承与Animation的自定义类
public class Rotate3dAnimation extends Animation {
private final float mFromDegrees;
private final float mToDegrees;
private final float mCenterX;
private final float mCenterY;
private final float mDepthZ;
private final boolean mReverse;
private Camera mCamera;
/**
* Creates a new 3D rotation on the Y axis. The rotation is defined by its
* start angle and its end angle. Both angles are in degrees. The rotation
* is performed around a center point on the 2D space, definied by a pair
* of X and Y coordinates, called centerX and centerY. When the animation
* starts, a translation on the Z axis (depth) is performed. The length
* of the translation can be specified, as well as whether the translation
* should be reversed in time.
*
* @param fromDegrees the start angle of the 3D rotation
* @param toDegrees the end angle of the 3D rotation
* @param centerX the X center of the 3D rotation
* @param centerY the Y center of the 3D rotation
* @param reverse true if the translation should be reversed, false otherwise
*/
public Rotate3dAnimation(float fromDegrees, float toDegrees,
float centerX, float centerY, float depthZ, boolean reverse) {
mFromDegrees = fromDegrees;
mToDegrees = toDegrees;
mCenterX = centerX;
mCenterY = centerY;
mDepthZ = depthZ;
mReverse = reverse;
}
@Override
public void initialize(int width, int height, int parentWidth, int parentHeight) {
super.initialize(width, height, parentWidth, parentHeight);
mCamera = new Camera();
}
@Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
final float fromDegrees = mFromDegrees;
float degrees = fromDegrees + ((mToDegrees - fromDegrees) * interpolatedTime);
final float centerX = mCenterX;
final float centerY = mCenterY;
final Camera camera = mCamera;
final Matrix matrix = t.getMatrix();
//保存一次camera初始状态,用于restore()
camera.save();
if (mReverse) {
camera.translate(0.0f, 0.0f, mDepthZ * interpolatedTime);
} else {
camera.translate(0.0f, 0.0f, mDepthZ * (1.0f - interpolatedTime));
}
//围绕X轴旋转degrees度
camera.rotateX(degrees);
//行camera中取出矩阵,赋值给matrix
camera.getMatrix(matrix);
//camera恢复到初始状态,继续用于下次的计算
camera.restore();
matrix.preTranslate(-centerX, -centerY);
matrix.postTranslate(centerX, centerY);
}
}
Rotate3dAnimation