生活随笔
收集整理的這篇文章主要介紹了
Android\OPhone动画分析之翻转效果
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
看到很多人在問如何實現(xiàn)三維的翻轉(zhuǎn)效果,所以今天在這里簡單的給大家分析一下,其實在APIDemo中就有這樣一個例子,那么我們就以其為例來學習Android中的翻轉(zhuǎn)動畫效果的實現(xiàn),首先看一下運行效果如下圖所示。
Android中并沒有提供直接做3D翻轉(zhuǎn)的動畫,所以關(guān)于3D翻轉(zhuǎn)的動畫效果需要我們自己實現(xiàn),那么我們首先來分析一下Animation 和 Transformation。
Animation動畫的主要接口,其中主要定義了動畫的一些屬性比如開始時間,持續(xù)時間,是否重復播放等等。而Transformation中則包含一個矩陣和alpha值,矩陣是用來做平移,旋轉(zhuǎn)和縮放動畫的,而alpha值是用來做alpha動畫的,要實現(xiàn)3D旋轉(zhuǎn)動畫我們需要繼承自Animation類來實現(xiàn),我們需要重載getTransformation和applyTransformation,在getTransformation中Animation會根據(jù)動畫的屬性來產(chǎn)生一系列的差值點,然后將這些差值點傳給applyTransformation,這個函數(shù)將根據(jù)這些點來生成不同的Transformation。下面是具體實現(xiàn):
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; ?????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); ?????} ?}? 其中包括了旋轉(zhuǎn)的開始和結(jié)束角度,中心點、是否扭曲、和一個Camera,這里我們主要分析applyTransformation函數(shù),其中第一個參數(shù)就是通過getTransformation函數(shù)傳遞的差指點,然后我們根據(jù)這個差值通過線性差值算法計算出一個中間角度degrees,Camera類是用來實現(xiàn)繞Y軸旋轉(zhuǎn)后透視投影的,因此我們首先通過t.getMatrix()取得當前的矩陣,然后通過camera.translate來對矩陣進行平移變換操作,camera.rotateY進行旋轉(zhuǎn)。這樣我們就可以很輕松的實現(xiàn)3D旋轉(zhuǎn)效果了,該例子的原意是通過一個列表來供用戶選擇要實現(xiàn)翻轉(zhuǎn)的圖像,所以我們分析至少需要定義兩個控件:ListView和ImageView(要翻轉(zhuǎn)的圖像),主界面的xml布局定義如下所示。
<FrameLayout?xmlns:android="http://schemas.android.com/apk/res/android"?????android:id="@+id/container"?????android:layout_width="match_parent"?????android:layout_height="match_parent">??????<ListView?????????android:id="@android:id/list"?????????android:persistentDrawingCache="animation|scrolling"?????????android:layout_width="match_parent"?????????android:layout_height="match_parent"?????????android:layoutAnimation="@anim/layout_bottom_to_top_slide"?/>??????<ImageView?????????android:id="@+id/picture"?????????android:scaleType="fitCenter"?????????android:layout_width="match_parent"?????????android:layout_height="match_parent"?????????android:visibility="gone"?/>??</FrameLayout>? 然后準備好需要的資源,在onCreate函數(shù)中準備好ListView和ImageView,因為要旋轉(zhuǎn)所以我們需要保存視圖的緩存信息,通過setPersistentDrawingCache(ViewGroup.PERSISTENT_ANIMATION_CACHE);可以設(shè)置該功能,當我們選擇列表中的圖像資源后在onItemClick中將選擇的資源Id對應(yīng)的圖像設(shè)置到ImageView中,然后通過applyRotation來啟動一個動畫,前面有了Rotate3dAnimation的實現(xiàn),我們要完成3D翻轉(zhuǎn)動畫就很簡單,直接構(gòu)建一個Rotate3dAnimation對象,設(shè)置其屬性(包括動畫監(jiān)聽),這里將動畫的監(jiān)聽設(shè)置為DisplayNextView,可以用來顯示下一個視圖,在其中的動畫結(jié)束監(jiān)聽(onAnimationEnd)中,通過一個縣城SwapViews來交換兩個畫面,交換過程則是設(shè)置ImageView和ListView的顯示相關(guān)屬性,并構(gòu)建一個Rotate3dAnimation對象,對另一個界面進行旋轉(zhuǎn)即可,然后啟動動畫,整個轉(zhuǎn)換過程實際上就是將第一個界面從0度轉(zhuǎn)好90度,然后就愛你過第二個界面從90度轉(zhuǎn)到0度,這樣就形成了一個翻轉(zhuǎn)動畫,完整代碼如下,我們也加入了一些必要的注解,大家也可以參考APIDemo中的Transition3d例子。
public?class?Transition3d?extends?Activity?implements?????????AdapterView.OnItemClickListener,?View.OnClickListener?{ ??????????private?ListView?mPhotosList; ?????private?ViewGroup?mContainer; ?????private?ImageView?mImageView; ???????????private?static?final?String[]?PHOTOS_NAMES?=?new?String[]?{ ?????????????"Lyon", ?????????????"Livermore", ?????????????"Tahoe?Pier", ?????????????"Lake?Tahoe", ?????????????"Grand?Canyon", ?????????????"Bodie"?????}; ???????????private?static?final?int[]?PHOTOS_RESOURCES?=?new?int[]?{ ?????????????R.drawable.photo1, ?????????????R.drawable.photo2, ?????????????R.drawable.photo3, ?????????????R.drawable.photo4, ?????????????R.drawable.photo5, ?????????????R.drawable.photo6 ?????}; ??????@Override?????protected?void?onCreate(Bundle?savedInstanceState)?{ ?????????super.onCreate(savedInstanceState); ??????????setContentView(R.layout.animations_main_screen); ??????????mPhotosList?=?(ListView)?findViewById(android.R.id.list); ?????????mImageView?=?(ImageView)?findViewById(R.id.picture); ?????????mContainer?=?(ViewGroup)?findViewById(R.id.container); ???????????????????final?ArrayAdapter<String>?adapter?=?new?ArrayAdapter<String>(this, ?????????????????android.R.layout.simple_list_item_1,?PHOTOS_NAMES); ??????????mPhotosList.setAdapter(adapter); ?????????mPhotosList.setOnItemClickListener(this); ???????????????????mImageView.setClickable(true); ?????????mImageView.setFocusable(true); ?????????mImageView.setOnClickListener(this); ???????????????????mContainer.setPersistentDrawingCache(ViewGroup.PERSISTENT_ANIMATION_CACHE); ?????} ?????????????????private?void?applyRotation(int?position,?float?start,?float?end)?{ ??????????????????final?float?centerX?=?mContainer.getWidth()?/?2.0f; ?????????final?float?centerY?=?mContainer.getHeight()?/?2.0f; ????????????????????????????final?Rotate3dAnimation?rotation?= ?????????????????new?Rotate3dAnimation(start,?end,?centerX,?centerY,?310.0f,?true); ?????????rotation.setDuration(500); ?????????rotation.setFillAfter(true); ?????????rotation.setInterpolator(new?AccelerateInterpolator()); ??????????????????rotation.setAnimationListener(new?DisplayNextView(position)); ??????????mContainer.startAnimation(rotation); ?????} ??????public?void?onItemClick(AdapterView?parent,?View?v,?int?position,?long?id)?{ ??????????????????mImageView.setImageResource(PHOTOS_RESOURCES[position]); ?????????applyRotation(position,?0,?90); ?????} ??????????public?void?onClick(View?v)?{ ?????????applyRotation(-1,?180,?90); ?????} ???????????????private?final?class?DisplayNextView?implements?Animation.AnimationListener?{ ?????????private?final?int?mPosition; ??????????private?DisplayNextView(int?position)?{ ?????????????mPosition?=?position; ?????????} ??????????public?void?onAnimationStart(Animation?animation)?{ ?????????} ??????????????????public?void?onAnimationEnd(Animation?animation)?{ ?????????????mContainer.post(new?SwapViews(mPosition)); ?????????} ??????????public?void?onAnimationRepeat(Animation?animation)?{ ?????????} ?????} ??????????????private?final?class?SwapViews?implements?Runnable?{ ?????????private?final?int?mPosition; ??????????public?SwapViews(int?position)?{ ?????????????mPosition?=?position; ?????????} ??????????public?void?run()?{ ?????????????final?float?centerX?=?mContainer.getWidth()?/?2.0f; ?????????????final?float?centerY?=?mContainer.getHeight()?/?2.0f; ?????????????Rotate3dAnimation?rotation; ????????????? ?????????????if?(mPosition?>?-1)?{ ??????????????????????????????????mPhotosList.setVisibility(View.GONE); ?????????????????mImageView.setVisibility(View.VISIBLE); ?????????????????mImageView.requestFocus(); ??????????????????rotation?=?new?Rotate3dAnimation(90,?180,?centerX,?centerY,?310.0f,?false); ?????????????}?else?{ ??????????????????????????????????mImageView.setVisibility(View.GONE); ?????????????????mPhotosList.setVisibility(View.VISIBLE); ?????????????????mPhotosList.requestFocus(); ??????????????????rotation?=?new?Rotate3dAnimation(90,?0,?centerX,?centerY,?310.0f,?false); ?????????????} ??????????????rotation.setDuration(500); ?????????????rotation.setFillAfter(true); ?????????????rotation.setInterpolator(new?DecelerateInterpolator()); ??????????????????????????mContainer.startAnimation(rotation); ?????????} ?????} ??}?
轉(zhuǎn)載于:https://blog.51cto.com/yarin/386219
創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎勵來咯,堅持創(chuàng)作打卡瓜分現(xiàn)金大獎
總結(jié)
以上是生活随笔為你收集整理的Android\OPhone动画分析之翻转效果的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。