Andorid 廣告頁3D旋轉進入主頁(仿ios Swift動畫 )

20170731131804631.gif
1,Android 原本一些overridePendingTransition 用來跳轉activity切換動畫,並不支援那麼完美的3d旋轉動畫,有些手機並不能支援
2,利用Activity繼承ActivityGroup(不支援使用該方法),包裹兩個Activity,通過獲取該view,addview到該Group的佈局中,經過測試,太卡
但是需求必須得做,就找到一個雞賊的辦法
1,廣告頁和主介面 寫在同一個Activity中
2,使用廣告頁覆蓋主頁面,在Activity動畫旋轉90度後,隱藏並把Activty反著旋轉90度,已達到以上圖片效果
3,把主介面中耗時操作,消耗效能操作,繪製操作等,儘量放在動畫結束之後。防止卡頓
Observable.just(1) .delay(2500, TimeUnit.MILLISECONDS) .observeOn(Schedulers.newThread()) .subscribeOn(AndroidSchedulers.mainThread()) .subscribe(new Consumer<Integer>() { @Override public void accept(Integer integer) throws Exception { if (go) { mboss.post(new Runnable() {//根部局繪製完成 @Override public void run() { Rotate3dAnimation flipAinm = new Rotate3dAnimation(MainActivity.this, 360, 270, centerX, centerY, 0f, true); flipAinm.setFillAfter(true); flipAinm.setAnimationListener(new Animation.AnimationListener() { @Override public void onAnimationStart(Animation animation) { } @Override public void onAnimationEnd(Animation animation) { mfragm_img.setVisibility(View.GONE); playFlip2Anim(); } @Override public void onAnimationRepeat(Animation animation) { } }); flipAinm.setInterpolator(new AccelerateInterpolator()); flipAinm.setDuration(800); mboss.clearAnimation(); mboss.startAnimation(flipAinm); } }); } } });
第一部分90度旋轉完成後,執行第二部分
private void playFlip2Anim(){ Rotate3dAnimation flipAinm = new Rotate3dAnimation(MainActivity.this, 90, 0, centerX, centerY, 0f, true); flipAinm.setFillAfter(true); flipAinm.setInterpolator(new AccelerateInterpolator()); flipAinm.setDuration(800); flipAinm.setAnimationListener(new Animation.AnimationListener() { @Override public void onAnimationStart(Animation animation) { } @Override public void onAnimationEnd(Animation animation) { //在此執行主介面邏輯 } @Override public void onAnimationRepeat(Animation animation) { } }); mboss.clearAnimation(); mboss.startAnimation(flipAinm); }
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; float scale = 1;// <------- 畫素密度 該值必須設定,防止旋轉動畫效果出現偏差 /** * 建立一個繞y軸旋轉的3D動畫效果,旋轉過程中具有深度調節,可以指定旋轉中心。 * @param context<------- 新增上下文,為獲取畫素密度準備 * @param fromDegrees 起始時角度 * @param toDegrees結束時角度 * @param centerX旋轉中心x座標 * @param centerY旋轉中心y座標 * @param depthZ最遠到達的z軸座標 * @param reversetrue 表示由從0到depthZ,false相反 */ public Rotate3dAnimation(Context context, float fromDegrees, float toDegrees, float centerX, float centerY, float depthZ, boolean reverse) { mFromDegrees = fromDegrees; mToDegrees = toDegrees; mCenterX = centerX; mCenterY = centerY; mDepthZ = depthZ; mReverse = reverse; // 獲取手機畫素密度 (即dp與px的比例) scale = context.getResources().getDisplayMetrics().density; } @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.save(); // 調節深度 if (mReverse) { camera.translate(0.0f, 0.0f, mDepthZ * interpolatedTime); } else { camera.translate(0.0f, 0.0f, mDepthZ * (1.0f - interpolatedTime)); } // 繞y軸旋轉 camera.rotateY(degrees); camera.getMatrix(matrix); camera.restore(); // 修正失真,主要修改 MPERSP_0 和 MPERSP_1 float[] mValues = new float[9]; matrix.getValues(mValues);//獲取數值 mValues[6] = mValues[6]/scale;//數值修正 mValues[7] = mValues[7]/scale;//數值修正 matrix.setValues(mValues);//重新賦值 // 調節中心點 matrix.preTranslate(-centerX, -centerY); matrix.postTranslate(centerX, centerY); } }