Andorid 广告页3D旋转进入主页(仿ios Swift动画
2018-09-17 本文已影响10人
Ready_I
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 reverse true 表示由从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);
}
}