This article mainly describes how to achieve the view of the 3D rotation effect, the main principle is to rotate around the y axis, while the z axis has an in-depth scaling.
Demo Demo mainly has the following key points:
1, custom rotation animation
2, after the animation is done, reset ImageView
Let's take a look at how the program works:
1, Custom Animation class
This implements a Rotate3danimation class that extends the animation class, rewrites the Applytransformation () method, and provides a matrix transformation of the specified time, and in this method, You can use the camera class to get a matrix that rotates around the Y axis, setting this matrix into a transformation object. The specific implementation code is as follows:
Copy Code code as follows:
@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));
}
Camera.rotatey (degrees);
Camera.getmatrix (matrix);
Camera.restore ();
Matrix.pretranslate (-centerx,-centery);
Matrix.posttranslate (CenterX, centery);
}
2, how to use this animation class
In the activity, we have two imageview of the same size, all of which are placed in the framelayout so that they overlap and animate the top ImageView (rotation angle from 0 to 90), and when the animation is done, Then animate the rear imageview (rotate angle from 90 to 180), where you want to control the corresponding ImageView hidden or displayed.
The listener of the animation is implemented as follows:
Copy Code code as follows:
Private Final class Displaynextview implements Animation.animationlistener {
public void Onanimationstart (Animation Animation) {
}
public void Onanimationend (Animation Animation) {
Mcontainer.post (New Swapviews ());
}
public void Onanimationrepeat (Animation Animation) {
}
}
When the animation is done, the code that executes is as follows:
Copy Code code as follows:
Private Final class Swapviews implements Runnable
{
@Override
public void Run ()
{
Mimageview1.setvisibility (View.gone);
Mimageview2.setvisibility (View.gone);
mindex++;
if (0 = = mindex% 2)
{
Mstartanimview = MImageView1;
}
Else
{
Mstartanimview = MImageView2;
}
Mstartanimview.setvisibility (view.visible);
Mstartanimview.requestfocus ();
Rotate3danimation rotation = new Rotate3danimation (
-90,
0,
Mcenterx,
Mcentery, Mdepthz, false);
Rotation.setduration (mduration);
Rotation.setfillafter (TRUE);
Rotation.setinterpolator (New Decelerateinterpolator ());
Mstartanimview.startanimation (rotation);
}
}
Click on the button's event handling implementation:
Copy Code code as follows:
@Override
public void OnClick (View v)
{
Mcenterx = Mcontainer.getwidth ()/2;
Mcentery = Mcontainer.getheight ()/2;
Getdepthz ();
Applyrotation (Mstartanimview, 0, 90);
}
The implementation of Applyrotation is as follows:
Copy Code code as follows:
private void Applyrotation (View animview, float startangle, float toangle)
{
float CenterX = Mcenterx;
float centery = mcentery;
Rotate3danimation rotation = new Rotate3danimation (
StartAngle, Toangle, CenterX, CenterY, Mdepthz, true);
Rotation.setduration (mduration);
Rotation.setfillafter (TRUE);
Rotation.setinterpolator (New Accelerateinterpolator ());
Rotation.setanimationlistener (New Displaynextview ());
Animview.startanimation (rotation);
}
3, the complete code is as follows
Rotate3danimactivity.java
Copy Code code as follows:
public class Rotate3danimactivity extends activity
{
ImageView mImageView1 = null;
ImageView mImageView2 = null;
ImageView Mstartanimview = null;
View mcontainer = null;
int mduration = 500;
float Mcenterx = 0.0f;
float mcentery = 0.0f;
float Mdepthz = 0.0f;
int mindex = 0;
@Override
public void OnCreate (Bundle savedinstancestate)
{
Super.oncreate (savedinstancestate);
Setcontentview (R.layout.rotate_anim);
MImageView1 = (ImageView) Findviewbyid (R.ID.IMAGEVIEW1);
MImageView2 = (ImageView) Findviewbyid (R.ID.IMAGEVIEW2);
Mcontainer = Findviewbyid (R.id.container);
Mstartanimview = MImageView1;
Findviewbyid (R.id.button1). Setonclicklistener (New View.onclicklistener ()
{
@Override
public void OnClick (View v)
{
Mcenterx = Mcontainer.getwidth ()/2;
Mcentery = Mcontainer.getheight ()/2;
Getdepthz ();
Applyrotation (Mstartanimview, 0, 90);
}
});
Inputmethodmanager IMM = (inputmethodmanager) getsystemservice (Input_method_service);
Imm.hidesoftinputfromwindow (GetWindow (). Getdecorview (). Getwindowtoken (), inputmethodmanager.hide_not_always);
}
private void Getdepthz ()
{
EditText EditText = (edittext) Findviewbyid (R.id.edit_depthz);
String string = Edittext.gettext (). toString ();
Try
{
Mdepthz = (float) integer.parseint (string);
Mdepthz = Math.min (Mdepthz, 300.0f);
}
catch (Exception e)
{
E.printstacktrace ();
}
}
private void Applyrotation (View animview, float startangle, float toangle)
{
float CenterX = Mcenterx;
float centery = mcentery;
Rotate3danimation rotation = new Rotate3danimation (
StartAngle, Toangle, CenterX, CenterY, Mdepthz, true);
Rotation.setduration (mduration);
Rotation.setfillafter (TRUE);
Rotation.setinterpolator (New Accelerateinterpolator ());
Rotation.setanimationlistener (New Displaynextview ());
Animview.startanimation (rotation);
}
/**
* This class is listens for the ' end of the ' the ' the ' half ' of the animation.
* It then posts a new action that effectively swaps the "views" when the container
* is rotated degrees and thus invisible.
*/
Private Final class Displaynextview implements Animation.animationlistener {
public void Onanimationstart (Animation Animation) {
}
public void Onanimationend (Animation Animation) {
Mcontainer.post (New Swapviews ());
}
public void Onanimationrepeat (Animation Animation) {
}
}
Private Final class Swapviews implements Runnable
{
@Override
public void Run ()
{
Mimageview1.setvisibility (View.gone);
Mimageview2.setvisibility (View.gone);
mindex++;
if (0 = = mindex% 2)
{
Mstartanimview = MImageView1;
}
Else
{
Mstartanimview = MImageView2;
}
Mstartanimview.setvisibility (view.visible);
Mstartanimview.requestfocus ();
Rotate3danimation rotation = new Rotate3danimation (
-90,
0,
Mcenterx,
Mcentery, Mdepthz, false);
Rotation.setduration (mduration);
Rotation.setfillafter (TRUE);
Rotation.setinterpolator (New Decelerateinterpolator ());
Mstartanimview.startanimation (rotation);
}
}
}
Rotate_anim.xml
Copy Code code as follows:
<?xml version= "1.0" encoding= "Utf-8"?>
<linearlayout xmlns:android= "Http://schemas.android.com/apk/res/android"
Android:layout_width= "Fill_parent"
android:layout_height= "Fill_parent"
android:orientation= "Vertical" >
<button
Android:id= "@+id/button1"
Android:layout_width= "Wrap_content"
android:layout_height= "Wrap_content"
Android:layout_margin= "20DP"
Android:text= "Do 3d animation"/>
<textview
Android:layout_width= "Wrap_content"
android:layout_height= "Wrap_content"
android:layout_marginleft= "20px"
android:text= "Input Depth on Z axis. [0, 300] "
/>
<edittext
Android:id= "@+id/edit_depthz"
Android:layout_width= "200DP"
android:layout_height= "Wrap_content"
Android:layout_margin= "20DP"
android:text= "0"/>
<framelayout
Android:id= "@+id/container"
Android:layout_width= "Wrap_content"
android:layout_height= "Wrap_content" >
<imageview
Android:id= "@+id/imageview1"
Android:layout_width= "200DP"
android:layout_height= "200DP"
Android:layout_margin= "20DP"
Android:src= "@drawable/F"/>
<imageview
Android:id= "@+id/imageview2"
Android:layout_width= "200DP"
android:layout_height= "200DP"
Android:layout_margin= "20DP"
Android:src= "@drawable/S"
android:visibility= "Gone"/>
</FrameLayout>
</LinearLayout>
Rotate3danimation.java
Copy Code code as follows:
Package Com.nj1s.lib.anim;
Import Android.graphics.Camera;
Import Android.graphics.Matrix;
Import android.view.animation.Animation;
Import android.view.animation.Transformation;
/**
* An animation which 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 spaces, 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 as the whether the translation
* Should is 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.save ();
if (mreverse) {
Camera.translate (0.0f, 0.0f, Mdepthz * interpolatedtime);
} else {
Camera.translate (0.0f, 0.0f, Mdepthz * (1.0f-interpolatedtime));
}
Camera.rotatey (degrees);
Camera.getmatrix (matrix);
Camera.restore ();
Matrix.pretranslate (-centerx,-centery);
Matrix.posttranslate (CenterX, centery);
}
}
Ladies and gentlemen, please think about the last reason why you should have these two sentences in order to realize the Applytransformation method:
Matrix.pretranslate (-centerx,-centery);
Matrix.posttranslate (CenterX, centery);