zoukankan      html  css  js  c++  java
  • android3D动画,绕y轴旋转

    原文地址:http://blog.csdn.net/x_i_a_o_h_a_i/article/details/40449847

    其实网上的3D旋转的例子很多,在这里我只是想把其代码做一个解释。

    先上图:

    代码:

    TurnAroundActivity

    /**
     * 图片浏览器的主Activity。
     * 
     * @author guolin
     */
    public class TurnAroundActivity extends Activity {
    
    	/**
    	 * 根布局
    	 */
    	private RelativeLayout layout;
    
    	/**
    	 * 用于展示图片列表的ListView
    	 */
    	private ListView picListView;
    
    	/**
    	 * 翻转后的布局
    	 */
    	private LinearLayout picture;
    
    	/**
    	 * 图片列表的适配器
    	 */
    	private PictureAdapter adapter;
    
    	/**
    	 * 存放所有图片的集合
    	 */
    	private List<Picture> picList = new ArrayList<Picture>();
    
    	@Override
    	protected void onCreate(Bundle savedInstanceState) {
    		super.onCreate(savedInstanceState);
    		requestWindowFeature(Window.FEATURE_NO_TITLE);
    		setContentView(R.layout.activity_around);
    		// 对图片列表数据进行初始化操作
    		initPics();
    		layout = (RelativeLayout) findViewById(R.id.layout);
    		picListView = (ListView) findViewById(R.id.pic_list_view);
    		picture = (LinearLayout) findViewById(R.id.picture);
    		adapter = new PictureAdapter(this, 0, picList);
    		picListView.setAdapter(adapter);
    		picListView.setOnItemClickListener(new OnItemClickListener() {
    			@Override
    			public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
    				
    				// 获取布局的中心点位置,作为旋转的中心点
    				float centerX = layout.getWidth() / 2f;
    				float centerY = layout.getHeight() / 2f;
    				// 构建3D旋转动画对象,旋转角度为0到90度,这使得ListView将会从可见变为不可见
    				final Rotate3dAnimation rotation = new Rotate3dAnimation(0, 90, centerX, centerY,
    						310.0f, true);
    				// 动画持续时间500毫秒
    				rotation.setDuration(500);
    				// 动画完成后保持完成的状态
    				rotation.setFillAfter(true);
    				rotation.setInterpolator(new AccelerateInterpolator());
    				// 设置动画的监听器
    				rotation.setAnimationListener(new TurnToImageView());
    				layout.startAnimation(rotation);
    			}
    		});
    		picture.setOnClickListener(new OnClickListener() {
    			@Override
    			public void onClick(View v) {
    				// 获取布局的中心点位置,作为旋转的中心点
    				float centerX = layout.getWidth() / 2f;
    				float centerY = layout.getHeight() / 2f;
    				// 构建3D旋转动画对象,旋转角度为360到270度,这使得ImageView将会从可见变为不可见,并且旋转的方向是相反的
    				final Rotate3dAnimation rotation = new Rotate3dAnimation(360, 270, centerX,
    						centerY, 310.0f, true);
    				// 动画持续时间500毫秒
    				rotation.setDuration(500);
    				// 动画完成后保持完成的状态
    				rotation.setFillAfter(true);
    				rotation.setInterpolator(new AccelerateInterpolator());
    				// 设置动画的监听器
    				rotation.setAnimationListener(new TurnToListView());
    				layout.startAnimation(rotation);
    			}
    		});
    	}
    
    	/**
    	 * 初始化图片列表数据。
    	 */
    	private void initPics() {
    		Picture bird = new Picture("Bird", R.drawable.bird);
    		picList.add(bird);
    		Picture winter = new Picture("Winter", R.drawable.winter);
    		picList.add(winter);
    		Picture autumn = new Picture("Autumn", R.drawable.autumn);
    		picList.add(autumn);
    		Picture greatWall = new Picture("Great Wall", R.drawable.great_wall);
    		picList.add(greatWall);
    		Picture waterFall = new Picture("Water Fall", R.drawable.water_fall);
    		picList.add(waterFall);
    	}
    
    	/**
    	 * 注册在ListView点击动画中的动画监听器,用于完成ListView的后续动画。
    	 * 
    	 * @author guolin
    	 */
    	class TurnToImageView implements AnimationListener {
    
    		@Override
    		public void onAnimationStart(Animation animation) {
    		}
    
    		/**
    		 * 当ListView的动画完成后,还需要再启动ImageView的动画,让ImageView从不可见变为可见
    		 */
    		@Override
    		public void onAnimationEnd(Animation animation) {
    			// 获取布局的中心点位置,作为旋转的中心点
    			float centerX = layout.getWidth() / 2f;
    			float centerY = layout.getHeight() / 2f;
    			// 将ListView隐藏
    			picListView.setVisibility(View.GONE);
    			// 将ImageView显示
    			picture.setVisibility(View.VISIBLE);
    			picture.requestFocus();
    			// 构建3D旋转动画对象,旋转角度为270到360度,这使得ImageView将会从不可见变为可见
    			final Rotate3dAnimation rotation = new Rotate3dAnimation(270, 360, centerX, centerY,
    					310.0f, false);
    			// 动画持续时间500毫秒
    			rotation.setDuration(500);
    			// 动画完成后保持完成的状态
    			rotation.setFillAfter(true);
    			rotation.setInterpolator(new AccelerateInterpolator());
    			layout.startAnimation(rotation);
    		}
    
    		@Override
    		public void onAnimationRepeat(Animation animation) {
    		}
    
    	}
    
    	/**
    	 * 注册在ImageView点击动画中的动画监听器,用于完成ImageView的后续动画。
    	 * 
    	 * @author guolin
    	 */
    	class TurnToListView implements AnimationListener {
    
    		@Override
    		public void onAnimationStart(Animation animation) {
    		}
    
    		/**
    		 * 当ImageView的动画完成后,还需要再启动ListView的动画,让ListView从不可见变为可见
    		 */
    		@Override
    		public void onAnimationEnd(Animation animation) {
    			// 获取布局的中心点位置,作为旋转的中心点
    			float centerX = layout.getWidth() / 2f;
    			float centerY = layout.getHeight() / 2f;
    			// 将ImageView隐藏
    			picture.setVisibility(View.GONE);
    			// 将ListView显示
    			picListView.setVisibility(View.VISIBLE);
    			picListView.requestFocus();
    			// 构建3D旋转动画对象,旋转角度为90到0度,这使得ListView将会从不可见变为可见,从而回到原点
    			final Rotate3dAnimation rotation = new Rotate3dAnimation(90, 0, centerX, centerY,
    					310.0f, false);
    			// 动画持续时间500毫秒
    			rotation.setDuration(500);
    			// 动画完成后保持完成的状态
    			rotation.setFillAfter(true);
    			rotation.setInterpolator(new AccelerateInterpolator());
    			layout.startAnimation(rotation);
    		}
    
    		@Override
    		public void onAnimationRepeat(Animation animation) {
    		}
    
    	}
    
    }


    关键类:

    Rotate3dAnimation
    /**
     * 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
    	 * @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();
    		//z轴上的景深
    		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();
    		//camera.rotateY(degrees);其实围绕y轴旋转的坐标点是在(0,0);
    		//为了让其在围绕(centerX, centerY)点
    		//preTranslate 作用为在rotateY开始之前先把坐标(centerX, centerY)移到中心点
    		matrix.preTranslate(-centerX, -centerY);
    		//postTranslate 当执行完rotateY后再把中心点移动回来
    		matrix.postTranslate(centerX, centerY);
    	}
    }


    layout文件:

    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/layout"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
         >
    
        <ListView
            android:id="@+id/pic_list_view"
            android:layout_width="match_parent"
            android:layout_height="match_parent" 
            >
        </ListView>
        
        <LinearLayout 
            android:id="@+id/picture"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:clickable="true"
            android:orientation="vertical"
            android:visibility="gone"
            >
            <TextView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:id="@+id/text"
                android:text="ddddddd"/>
            <ImageView 
                android:layout_width="200dp"
                android:layout_height="200dp"
                android:src="@drawable/bird"
                />
            <Button android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="ddddddd"/>
            
        </LinearLayout>
    
    </RelativeLayout>
  • 相关阅读:
    每天一点点之css
    【Vue中的坑】Vue中的修改变量没有效果?
    每天一点点之vue框架开发
    每天一点点之laravel框架开发
    每天一点点之vue框架开发
    推荐几款好用的办公软件
    每天一点点之vue框架开发
    Unity3D调用摄像头,画面为翻转的问题
    正确显示竖屏预览和拍照的照片
    卡尔曼滤波简介+ 算法实现代码
  • 原文地址:https://www.cnblogs.com/BlogCommunicator/p/4976686.html
Copyright © 2011-2022 走看看