The author | Kevin_Android

Address | http://www.jianshu.com/p/65f50b6ecaca

Statement | this is the original Kevin_Android, release has been authorized, without author permission please do not reprint

rendering

This article implements the 3D flip effect of dialog in Android. Here is a simple application scenario.

Analysis of the

At first, MY idea was to jump into the interface of the Activity to realize the rotation effect. I read a lot on the Internet and found the effect was wrong when I wrote it down. Then you see the Card Flid Animation on Google looks like this.

It looked good, but when I took the demo down and slowed it down, IT wasn’t what I wanted. However, it is the same as the effect I saw in an app and then tried to change it to dialog to try the effect, but found that it is even worse.

The effect of Card Flid Animation is as follows: This is implemented by switching fragments through the Activity. It can be seen that the difference is that it seems to become larger when flipped, but actually it is useless. It is just a visual problem after flipped.

I heard that openGl is cumbersome and I haven’t used it. Then I searched Rotate3DAnimaitons. Search in http://blog.csdn.net/growing_tree/article/details/50428148, so this article method of this article is not my original, refer to the other. Thank the great god here. But this one is in the activity, I just want a dialog effect, because the 3D effect of TIM’s opening a red envelope on the computer looks good, but in fact it is similar, so I took it and changed it into a dialog. The article of Rotate3DAnimaitons has been very detailed, you can refer to it if necessary.

I’ll also post the code for Rotate3dAnimation here

/** * An animation that rotates the view on the Y axis between two specified angles. * This animation also adds a translation on the Z axis (depth) to improve the effect. */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 // Start Angle * @param toDegrees the end Angle of the 3D rotation // End Angle * @param centerX the X center of the 3D Rotation //x axis * @param centerY the Y center of the 3D rotation // Y axis * @param reverse true if the translation should Public Rotate3dAnimation(float fromDegrees, float toDegrees, float centerX, public Rotate3dAnimation(float fromDegrees, float toDegrees, float centerX, float centerY, float depthZ, boolean reverse) { mFromDegrees = fromDegrees; mToDegrees = toDegrees; mCenterX = centerX; mCenterY = centerY; mDepthZ = depthZ; // The distance of z-axis movement, which affects the visual effect, can solve the seemingly magnified effect of Flip Animation 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(); Log.i("interpolatedTime", interpolatedTime+""); camera.save(); If (mReverse) {camera. Translate (0.0f, 0.0f, mDepthZ * interpolatedTime); } else {camera. Translate (0.0f, 0.0f, mDepthZ * (0.0f-interpolatedTime)); } camera.rotateY(degrees); camera.getMatrix(matrix); camera.restore(); matrix.preTranslate(-centerX, -centerY); matrix.postTranslate(centerX, centerY); }}Copy the code

Dialog implements 3D flip code

public class MyDialog extends Dialog { @BindView(R.id.et_user_name) EditText etUserName; @BindView(R.id.et_password) EditText etPassword; @BindView(R.id.cb_auto_login) CheckBox cbAutoLogin; @BindView(R.id.tv_forget_pwd) TextView tvForgetPwd; @BindView(R.id.ll_content) LinearLayout llContent; @BindView(R.id.et_email) EditText etEmail; @BindView(R.id.btn_back) Button btnBack; @BindView(R.id.container) RelativeLayout container; private Context context; @BindView(R.id.ll_register) LinearLayout llRegister; Private OnClickListenerInterface mListener; private View view; // private String strContent; private int centerX; private int centerY; private int depthZ = 700; Private int duration = 300; private int duration = 300; Private Rotate3dAnimation openAnimation; private Rotate3dAnimation closeAnimation; private boolean isOpen = false; Public interface OnClickListenerInterface {/** * confirm, */ void doConfirm(); // public void doCancel(); } public MyDialog(Context context) { super(context); this.context = context; } public MyDialog(Context context, String content) { super(context); this.context = context; this.strContent = content; } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); / / remove system of black rectangle getWindow () setBackgroundDrawableResource (android. R.c olor. Transparent); requestWindowFeature(Window.FEATURE_NO_TITLE); init(); } public void init() { LayoutInflater inflater = LayoutInflater.from(context); view = inflater.inflate(R.layout.dialog_my, null); setContentView(view); ButterKnife.bind(this); etPassword.setTypeface(Typeface.DEFAULT); etPassword.setTransformationMethod(new PasswordTransformationMethod()); tvForgetPwd.setOnClickListener(new OnWidgetClickListener()); btnBack.setOnClickListener(new OnWidgetClickListener()); Window dialogWindow = getWindow(); WindowManager.LayoutParams lp = dialogWindow.getAttributes(); DisplayMetrics d = context.getResources().getDisplayMetrics(); Width = (int) (d.widthPixels * 0.8); Height = (int) (d.eightEightPixels * 0.6); / / height is set to screen 0.6 dialogWindow. SetAttributes (lp); setCanceledOnTouchOutside(false); setCancelable(true); } public void setClicklistener(OnClickListenerInterface clickListenerInterface) { this.mListener = clickListenerInterface; } private class OnWidgetClickListener implements View.OnClickListener { @Override public void onClick(View v) { int id =  v.getId(); switch (id) { case R.id.tv_forget_pwd: startAnimation(); break; case R.id.btn_back: startAnimation(); break; }}} private void startAnimation() {centerX = container.getwidth () / 2; centerY = container.getHeight() / 2; if (openAnimation == null) { initOpenAnim(); initCloseAnim(); } // If (openanimation.hasStarted () &&! openAnimation.hasEnded()) { return; } if (closeAnimation.hasStarted() && ! closeAnimation.hasEnded()) { return; } if (isOpen) {container.startAnimation(openAnimation); } else { container.startAnimation(closeAnimation); } isOpen = ! isOpen; Private void initOpenAnim() {// Rotate the view clockwise from 0 to 90 degrees, the reverse parameter is true, and the view becomes invisible at the end of the animation when 90 degrees are reached.  openAnimation = new Rotate3dAnimation(0, 90, centerX, centerY, depthZ, true); openAnimation.setDuration(duration); openAnimation.setFillAfter(true); openAnimation.setInterpolator(new AccelerateInterpolator()); openAnimation.setAnimationListener(new Animation.AnimationListener() { @Override public void onAnimationStart(Animation animation) { } @Override public void onAnimationRepeat(Animation animation) { } @Override public void onAnimationEnd(Animation animation) { llRegister.setVisibility(View.GONE); llContent.setVisibility(View.VISIBLE); // Rotate the view clockwise from 270 to 360 degrees with the reverse parameter set to false, Rotate3dAnimation = new Rotate3dAnimation(270, 360, centerX, centerY, depthZ, false); rotateAnimation.setDuration(duration); rotateAnimation.setFillAfter(true); rotateAnimation.setInterpolator(new DecelerateInterpolator()); container.startAnimation(rotateAnimation); }}); } private void initCloseAnim() { closeAnimation = new Rotate3dAnimation(360, 270, centerX, centerY, depthZ, true); closeAnimation.setDuration(duration); closeAnimation.setFillAfter(true); closeAnimation.setInterpolator(new AccelerateInterpolator()); closeAnimation.setAnimationListener(new Animation.AnimationListener() { @Override public void onAnimationStart(Animation  animation) { } @Override public void onAnimationRepeat(Animation animation) { } @Override public void onAnimationEnd(Animation animation) { llRegister.setVisibility(View.VISIBLE); llContent.setVisibility(View.GONE); Rotate3dAnimation rotateAnimation = new Rotate3dAnimation(90, 0, centerX, centerY, depthZ, false); rotateAnimation.setDuration(duration); rotateAnimation.setFillAfter(true); rotateAnimation.setInterpolator(new DecelerateInterpolator()); container.startAnimation(rotateAnimation); }}); }}Copy the code

Note: animation part of the code is to take the search of the article.

Download the demo

http://download.csdn.net/download/student9128/9938049

The related

1 custom Drawable to achieve smart red Carp animation (Part 1)

6 benefits (complimentary books), 5 months of selected dry goods, thank you and code students grow together

day

more

fine

The color

Wechat id: Code-Xiaosheng

The public,

“Code Student”