import android.app.Activity;
import android.os.Bundle;
import java.util.concurrent.ThreadPoolExecutor.DiscardOldestPolicy;
import android.app.Activity;
import android.os.Bundle;
import android.util.DisplayMetrics;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.LinearLayout;
public class Y3DActivity extends Activity {
private ViewGroup layoutmain;//第一页面
private ViewGroup layoutnext;//第二页面
private Button btn_MainLast;//两个页面的四个按钮
private Button btn_MainNext;
private Button btn_NextLast;
private Button btn_NextNext;
private Rotate3D lQuest1Animation;//动画,一次点击按钮会触发两个动画播放
private Rotate3D lQuest2Animation;
private Rotate3D rQuest1Animation;
private Rotate3D rQuest2Animation;
private int mCenterX = 160; // 320x480X中心位置,旋转时需要用到
private int mCenterY = 240; // 320x480Y中心位置
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
initAnimation();//初始化动画
initMain();//初始化第一个页面
}
//初始化第一个页面
private void initMain(){
setContentView(R.layout.main);
layoutmain = (LinearLayout)findViewById(R.id.layout_main);
btn_MainLast = (Button)findViewById(R.id.main_last);
btn_MainNext = (Button)findViewById(R.id.main_next);
btn_MainLast.setOnClickListener(listener);
btn_MainNext.setOnClickListener(listener);
}
//初始化第二个页面
private void initNext(){
setContentView(R.layout.next);
layoutnext = (LinearLayout)findViewById(R.id.layout_next);
btn_NextLast = (Button)findViewById(R.id.next_last);
btn_NextNext = (Button)findViewById(R.id.next_next);
btn_NextLast.setOnClickListener(listener);
btn_NextNext.setOnClickListener(listener);
}
private View.OnClickListener listener = new View.OnClickListener() {
public void onClick(View v) {
switch (v.getId()) {
//整个过程是这样的:当第一个页面按上一页时,当前页面向左转90度,(0,-90)
//这时初始化第二个页面的布局,然后使用动画使它从右到左旋转到当前页面,(90,0)
case R.id.main_last: // 当前页是第一页,上一页
// 当前页向左旋转(0,-90)
layoutmain.startAnimation(lQuest1Animation);
initNext();
// 下一页向左旋转(90, 0)
layoutnext.startAnimation(lQuest2Animation);
break;
case R.id.main_next: // 下一页
//0,90
layoutmain.startAnimation(rQuest1Animation);
initNext();
//-90,0
layoutnext.startAnimation(rQuest2Animation);
break;
case R.id.next_last://当前页是第二页,上一页
//0,-90
layoutnext.startAnimation(lQuest1Animation);
initMain();
//90,0
layoutmain.startAnimation(lQuest2Animation);
break;
case R.id.next_next://同理
layoutnext.startAnimation(rQuest1Animation);
initMain();
layoutmain.startAnimation(rQuest2Animation);
break;
}
}
};
public void initAnimation() {
// 获取旋转中心
DisplayMetrics dm = new DisplayMetrics();
dm = getResources().getDisplayMetrics();
mCenterX = dm.widthPixels / 2;
mCenterY = dm.heightPixels / 2;
// 定义旋转方向
int duration = 1000;//动画时间
// 下一页的【question1】旋转方向(从0度转到-90,参考系为水平方向为0度)
lQuest1Animation = new Rotate3D(0,-90, mCenterX, mCenterY);
lQuest1Animation.setFillAfter(true);//当动画执行完后,控件将停留在执行结束的状态
//lQuest1Animation.setFillBefore(true);
lQuest1Animation.setDuration(duration);
// 下一页的【question2】旋转方向(从90度转到0,参考系为水平方向为0度)(起始第一题)
lQuest2Animation = new Rotate3D(90, 0, mCenterX, mCenterY);
lQuest2Animation.setFillAfter(true);
//lQuest1Animation.setFillBefore(true);
lQuest2Animation.setDuration(duration);
// 上一页的【question1】旋转方向(从0度转到90,参考系为水平方向为0度)
rQuest1Animation = new Rotate3D(0, 90, mCenterX, mCenterY);
rQuest1Animation.setFillAfter(true);
//lQuest1Animation.setFillBefore(true);
rQuest1Animation.setDuration(duration);
// 上一页的【question2】旋转方向(从-90度转到0,参考系为水平方向为0度)
rQuest2Animation = new Rotate3D(-90, 0, mCenterX, mCenterY);
rQuest2Animation.setFillAfter(true);
//lQuest1Animation.setFillBefore(true);
rQuest2Animation.setDuration(duration);
}
}
package yy.android.roate;
import android.graphics.Camera;
import android.graphics.Matrix;
import android.view.animation.AlphaAnimation;
import android.view.animation.Animation;
import android.view.animation.Transformation;
public class Rotate3D extends Animation {
private float fromDegree; //旋转启始角度
private float toDegree; //旋转终止角度
private float mCenterX; //旋转中心
private float mCenterY; //旋转中心
private Camera mCamera;
//初始化
public Rotate3D(float fromDegree, float toDegree, float centerX, float centerY) {
this.fromDegree = fromDegree;
this.toDegree = toDegree;
this.mCenterX = centerX;
this.mCenterY = centerY;
}
@Override//动画初始化
public void initialize(int width, int height, int parentWidth, int parentHeight) {
super.initialize(width, height, parentWidth, parentHeight);
mCamera = new Camera();//创建一个摄像头
}
@Override//在动画播放期间,且interpolatedTime为1.0前不断调用
//参数一:0.0-0.1时间,它会从0.0逐渐变成0.1.参数二:是代表动画要变换的动作,可以从它获得当前的变化矩阵matrix
protected void applyTransformation(float interpolatedTime, Transformation t) {
final float FromDegree = fromDegree;
//旋转角度,随着时间的变化,从初始角度逐渐变为目标角度
float degrees = FromDegree + (toDegree - fromDegree) * interpolatedTime;
final float centerX = mCenterX;
final float centerY = mCenterY;
final Matrix matrix = t.getMatrix(); //获得当前的转换矩阵
if (degrees <= -76.0f) {
degrees = -90.0f;
mCamera.save();//保存
mCamera.rotateY(degrees);//旋转,这样是当前页面垂直于屏幕所以就看不见了
mCamera.getMatrix(matrix);//获得摄像头当前的转换矩阵,然后在赋给matrix
mCamera.restore();//恢复
} else if (degrees >= 76.0f) {//同理
degrees = 90.0f;
mCamera.save();
//mCamera.translate(0, 0,centerX);
mCamera.rotateY(degrees);
//mCamera.translate(0, 0,-centerX );
mCamera.getMatrix(matrix);
mCamera.restore();
} else {//当没转的临界角76度时,都是执行以下动作
mCamera.save(); //保存
mCamera.translate(0, 0,centerX);//向Z轴方向移动160,也就是一半X的距离,用来设置摄像头的高度
mCamera.rotateY(degrees);//沿Y轴方向旋转,degrees是随着时间慢慢趋向距目标值的
mCamera.translate(0, 0,-centerX );
//获得摄像头当前的转换矩阵,然后在赋给matrix,不用这句的话,前面都所有动作时无效的
mCamera.getMatrix(matrix);
mCamera.restore();//恢复
}//为什么要把摄像头设置成Z方向为X方向的一半,是因为要达到正方形的旋转效果,而一切
//设置翻转中心点
matrix.preTranslate(-centerX, -centerY);//平移到(-320,-480)坐标处
matrix.postTranslate(centerX, centerY);//
}
}
/
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">Rotate 3D</string>
<string name="txt_main">第一页 \n\Android 3D</string>
<string name="txt_next">第二页 \n\宇智波YI</string>
</resources>
///
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/layout_main"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="@+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:gravity="center"
android:textColor="#ff0000"
android:text="@string/txt_main"/>
<LinearLayout
android:layout_marginTop="5dip"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:layout_gravity="center" >
<Button
android:id="@+id/main_last"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="上一頁"/>
<Button
android:id="@+id/main_next"
android:layout_marginLeft="50dip"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="下一頁"/>
</LinearLayout>
</LinearLayout>
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/layout_next"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="@+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:gravity="center"
android:textColor="#ff0000"
android:text="@string/txt_next"/>
<LinearLayout
android:layout_marginTop="5dip"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:layout_gravity="center" >
<Button
android:id="@+id/next_last"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="上一頁"/>
<Button
android:id="@+id/next_next"
android:layout_marginLeft="50dip"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="下一頁"/>
</LinearLayout>
</LinearLayout>