微信扫一扫

028-83195727 , 15928970361
business@forhy.com

3D翻转实现

翻转,水平转动2016-05-31

对于转动的效果 安卓本身有了旋转,可是翻转怎么实现呢?

先看效果图

申明 :翻转源码来源于Andbase


首先,看下来看下项目的布局文件 (一个帧布局中放了两个ImageButton,这里注意第二个ImageButoon是要给他设置消失的)

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.example.drotate.MainActivity" >

    <FrameLayout
        android:id="@+id/container"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        >


            <ImageButton
                android:id="@+id/right_image_one"
                android:layout_width="100dp"
                android:layout_height="100dp"
                android:layout_gravity="center"
                android:background="@drawable/yuan1_f"
                />
            <ImageButton
                android:id="@+id/right_image_one_ed"
                android:visibility="gone"
                android:layout_width="100dp"
                 android:layout_gravity="center"
                android:layout_height="100dp"
                android:background="@drawable/yuan1_z"
                 />
    </FrameLayout>

</RelativeLayout>

其次Activity的代码:

public class MainActivity extends Activity {
	private ViewGroup mContainer;
	private ImageView right_image_one, right_image_one_ed;
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		mContainer = (ViewGroup) findViewById(R.id.container);
		right_image_one = (ImageView) findViewById(R.id.right_image_one);
		right_image_one_ed = (ImageView) findViewById(R.id.right_image_one_ed);
		
		right_image_one.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				new Start3DUtil(0,0,90,mContainer,right_image_one,right_image_one_ed);
			}
		});
		right_image_one_ed.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View v) {
				new Start3DUtil(-1, 180, 90,mContainer,right_image_one,right_image_one_ed);
			}
		});

就是这么简单就能够实现 ,相信大家都能够看懂,

最后我们看下Start3DUtil的方法

它实现的翻转中两段动画中的第一段翻转,

public Start3DUtil(int position, float start, float end, View mContainer,View view1, View view2) {
		// 找翻转的中心点
		final float centerX = mContainer.getWidth() / 2.0f;
		final float centerY = mContainer.getHeight() / 2.0f;

		// Create a new 3D rotation with the supplied parameter
		// The animation listener is used to trigger the next animation
		final AbRotate3dAnimation rotation = new AbRotate3dAnimation(start,end, centerX, centerY, 310.0f, true);
		rotation.setDuration(500);
		rotation.setFillAfter(true);
		rotation.setInterpolator(new AccelerateInterpolator());//插值器
		rotation.setAnimationListener(new DisplayNextView(position, mContainer,view1, view2));

		mContainer.startAnimation(rotation);
	}

这里的 AbRotate3dAnimation就是翻转的具体实现的方法,我们来看下最主要的实现方法是

 @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);
    }
用到的类Camera(android.graphics.Camera 包名不要搞错) 和 Matrix (android.graphics.Matrix;)


DisplayNextView自定义的动画监听,实现在动画技术是对容器翻转完成的第二段动画,做到两个View的调换

public void onAnimationEnd(Animation animation) {
			mContainer.post(new SwapViews(mPosition, mContainer, view1, view2));
		}


private final class SwapViews implements Runnable {
		private final int mPosition;
		private final View mContainer, view1, view2;

		public SwapViews(int position, View container, View view1, View view2) {
			mPosition = position;
			this.view1 = view1;
			mContainer = container;
			this.view2 = view2;
		}

		public void run() {
			final float centerX = mContainer.getWidth() / 2.0f;
			final float centerY = mContainer.getHeight() / 2.0f;
			AbRotate3dAnimation rotation;

			if (mPosition > -1) {
				view1.setVisibility(View.GONE);
				view2.setVisibility(View.VISIBLE);

				rotation = new AbRotate3dAnimation(90, 180, centerX, centerY,310.0f, false);
			} else {
				view1.setVisibility(View.VISIBLE);
				view2.setVisibility(View.GONE);
				rotation = new AbRotate3dAnimation(90, 0, centerX, centerY,310.0f, false);
			}

			rotation.setDuration(500);
			rotation.setFillAfter(true);
			rotation.setInterpolator(new DecelerateInterpolator());

			mContainer.startAnimation(rotation);
		}
	}

}


最后demo的下载地址:http://www.oschina.net/code/snippet_2702417_56319

注,这里有一个bug,就是第二张ImageButton显示的图片在手机上翻转后的左右方向是反的