前面介紹了利用Android內建的控制項,進行滑動翻頁製作效果,現在我們通過代碼實現一些滑動翻頁的動畫效果。
Animation實現動畫有兩個方式:幀動畫(frame-by-frame animation)和補間動畫(tweened animation)
本樣本通過繼承Animation自訂Rotate3D,實現3D翻頁效果。如下:
1、Rotate3D(Animation)
首先,自訂Animation的3D動畫類Rotate3D
public class Rotate3D extends Animation {<br />private float fromDegree;// 旋轉起始角度<br />private float toDegree;// 旋轉終止角度<br />private float mCenterX;// 旋轉中心x<br />private float mCenterY;// 旋轉中心y<br />private Camera mCamera;</p><p>public Rotate3D(float fromDegree, float toDegree, float centerX, float centerY) {<br />this.fromDegree = fromDegree;<br />this.toDegree = toDegree;<br />this.mCenterX = centerX;<br />this.mCenterY = centerY;</p><p>}</p><p>@Override<br />public void initialize(int width, int height, int parentWidth, int parentHeight) {<br />super.initialize(width, height, parentWidth, parentHeight);<br />mCamera = new Camera();<br />}</p><p>@Override<br />protected void applyTransformation(float interpolatedTime, Transformation t) {<br />final float FromDegree = fromDegree;<br />float degrees = FromDegree + (toDegree - fromDegree) * interpolatedTime;// 旋轉角度(angle)<br />final float centerX = mCenterX;<br />final float centerY = mCenterY;<br />final Matrix matrix = t.getMatrix();</p><p>if (degrees <= -76.0f) {<br />degrees = -90.0f;<br />mCamera.save();<br />mCamera.rotateY(degrees);// 旋轉<br />mCamera.getMatrix(matrix);<br />mCamera.restore();<br />} else if (degrees >= 76.0f) {<br />degrees = 90.0f;<br />mCamera.save();<br />mCamera.rotateY(degrees);<br />mCamera.getMatrix(matrix);<br />mCamera.restore();<br />} else {<br />mCamera.save();<br />mCamera.translate(0, 0, centerX);// 位移x<br />mCamera.rotateY(degrees);<br />mCamera.translate(0, 0, -centerX);<br />mCamera.getMatrix(matrix);<br />mCamera.restore();<br />}</p><p>matrix.preTranslate(-centerX, -centerY);<br />matrix.postTranslate(centerX, centerY);<br />}<br />}
然後,執行個體化Rotate3D的旋轉方向
public void initAnimation() {<br />// 擷取旋轉中心<br />DisplayMetrics dm = new DisplayMetrics();<br />dm = getResources().getDisplayMetrics();<br />mCenterX = dm.widthPixels / 2;<br />mCenterY = dm.heightPixels / 2;</p><p>// 定義旋轉方向<br />int duration = 1000;<br />lQuest1Animation = new Rotate3D(0, -90, mCenterX, mCenterY);// 下一頁的【question1】旋轉方向(從0度轉到-90,參考係為水平方向為0度)<br />lQuest1Animation.setFillAfter(true);<br />lQuest1Animation.setDuration(duration);</p><p>lQuest2Animation = new Rotate3D(90, 0, mCenterX, mCenterY);// 下一頁的【question2】旋轉方向(從90度轉到0,參考係為水平方向為0度)(起始第一題)<br />lQuest2Animation.setFillAfter(true);<br />lQuest2Animation.setDuration(duration);</p><p>rQuest1Animation = new Rotate3D(0, 90, mCenterX, mCenterY);// 上一頁的【question1】旋轉方向(從0度轉到90,參考係為水平方向為0度)<br />rQuest1Animation.setFillAfter(true);<br />rQuest1Animation.setDuration(duration);</p><p>rQuest2Animation = new Rotate3D(-90, 0, mCenterX, mCenterY);// 上一頁的【question2】旋轉方向(從-90度轉到0,參考係為水平方向為0度)<br />rQuest2Animation.setFillAfter(true);<br />rQuest2Animation.setDuration(duration);<br />}
2、Activity
首先,定義兩個布局檔案,用於旋轉的畫面切換
main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"<br />android:id="@+id/layout_main"<br />android:layout_width="fill_parent"<br />android:layout_height="wrap_content"<br />android:orientation="vertical"></p><p>...</p><p></LinearLayout>
next.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"<br />android:id="@+id/layout_next"<br />android:layout_width="fill_parent"<br />android:layout_height="wrap_content"<br />android:orientation="vertical"></p><p>...</p><p></LinearLayout>限於篇幅,完整布局檔案請詳見源碼 ^_^
然後,初始化兩個旋轉的布局檔案資源
private void initMain(){<br /> setContentView(R.layout.main);</p><p>layoutmain = (LinearLayout)findViewById(R.id.layout_main);<br />btn_MainLast = (Button)findViewById(R.id.main_last);<br />btn_MainNext = (Button)findViewById(R.id.main_next);</p><p>btn_MainLast.setOnClickListener(listener);<br />btn_MainNext.setOnClickListener(listener);<br />}</p><p>private void initNext(){<br /> setContentView(R.layout.next);</p><p>layoutnext = (LinearLayout)findViewById(R.id.layout_next);<br />btn_NextLast = (Button)findViewById(R.id.next_last);<br />btn_NextNext = (Button)findViewById(R.id.next_next);</p><p>btn_NextLast.setOnClickListener(listener);<br />btn_NextNext.setOnClickListener(listener);<br />}
最後,設定布局檔案中的按鈕監聽事件,響應3D旋轉動畫和方向
private View.OnClickListener listener = new View.OnClickListener() {<br />@Override<br />public void onClick(View v) {<br />switch (v.getId()) {<br />case R.id.main_last:// 上一頁<br />layoutmain.startAnimation(lQuest1Animation);// 當前頁向左旋轉(0,-90)<br />initNext();<br />layoutnext.startAnimation(lQuest2Animation);// 下一頁向左旋轉(90, 0)<br />break;<br />case R.id.main_next:// 下一頁<br />layoutmain.startAnimation(rQuest1Animation);// 當前頁向右旋轉(0,90)<br />initNext();<br />layoutnext.startAnimation(rQuest2Animation);// 下一頁向右旋轉(-90, 0)<br />break;<br />case R.id.next_last:<br />layoutnext.startAnimation(lQuest1Animation);<br />initMain();<br />layoutmain.startAnimation(lQuest2Animation);<br />break;<br />case R.id.next_next:<br />layoutnext.startAnimation(rQuest1Animation);<br />initMain();<br />layoutmain.startAnimation(rQuest2Animation);<br />break;<br />}<br />}<br />};
源碼下載
參考推薦:
animation