在一个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 = 0; 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, 0, 360); 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 = 0; 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, 0, 360); 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(500); 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的自定义类
1 public class Rotate3dAnimation extends Animation { 2 private final float mFromDegrees; 3 private final float mToDegrees; 4 private final float mCenterX; 5 private final float mCenterY; 6 private final float mDepthZ; 7 private final boolean mReverse; 8 private Camera mCamera; 9 /** 10 * Creates a new 3D rotation on the Y axis. The rotation is defined by its 11 * start angle and its end angle. Both angles are in degrees. The rotation 12 * is performed around a center point on the 2D space, definied by a pair 13 * of X and Y coordinates, called centerX and centerY. When the animation 14 * starts, a translation on the Z axis (depth) is performed. The length 15 * of the translation can be specified, as well as whether the translation 16 * should be reversed in time. 17 * 18 * @param fromDegrees the start angle of the 3D rotation 19 * @param toDegrees the end angle of the 3D rotation 20 * @param centerX the X center of the 3D rotation 21 * @param centerY the Y center of the 3D rotation 22 * @param reverse true if the translation should be reversed, false otherwise 23 */24 public Rotate3dAnimation(float fromDegrees, float toDegrees, 25 float centerX, float centerY, float depthZ, boolean reverse) { 26 mFromDegrees = fromDegrees; 27 mToDegrees = toDegrees; 28 mCenterX = centerX; 29 mCenterY = centerY; 30 mDepthZ = depthZ; 31 mReverse = reverse; 32 } 33 @Override34 public void initialize(int width, int height, int parentWidth, int parentHeight) { 35 super.initialize(width, height, parentWidth, parentHeight); 36 mCamera = new Camera(); 37 } 38 @Override39 protected void applyTransformation(float interpolatedTime, Transformation t) {40 final float fromDegrees = mFromDegrees; 41 float degrees = fromDegrees + ((mToDegrees - fromDegrees) * interpolatedTime); 42 final float centerX = mCenterX; 43 final float centerY = mCenterY; 44 final Camera camera = mCamera; 45 final Matrix matrix = t.getMatrix();46 //保存一次camera初始状态,用于restore() 47 camera.save(); 48 if (mReverse) { 49 camera.translate(0.0f, 0.0f, mDepthZ * interpolatedTime); 50 } else { 51 camera.translate(0.0f, 0.0f, mDepthZ * (1.0f - interpolatedTime)); 52 } 53 //围绕X轴旋转degrees度54 camera.rotateX(degrees);55 //行camera中取出矩阵,赋值给matrix 56 camera.getMatrix(matrix); 57 //camera恢复到初始状态,继续用于下次的计算 58 camera.restore();59 matrix.preTranslate(-centerX, -centerY);60 matrix.postTranslate(centerX, centerY); 61 } 62 }