Android魔法(第二弹)——一步步实现淹没、展开效果
目錄
1、效果展示
2、動畫分析
3、整體布局
4、源碼解析
5、知識點總結
ObjectAnimator
ViewWrapper
源碼:
本篇文章我們實現一個簡單的動畫效果,目的是熟悉和加深Android屬性動畫的使用。另外這次我們使用kotlin來進行開發,不熟悉kotlin的同學可以自行簡單了解一下kotlin語法,基本應該能看懂
我們知道,android的View Animation動畫可以移動、放大等效果,但是不能改變布局的實際屬性。比如使用scaleAnimation使布局縮放,但是布局的實際大小并沒有改變,所以會遮蓋旁邊的布局,并不是把布局撐開,擠壓其他布局。
1、效果展示
現在我們要實現一種效果如下: 這時候使用ViewAnimation就會比較麻煩,所以我們使用ObjectAnimator來實現。2、動畫分析
這個效果一共有三個狀態: (狀態1) (狀態2)?(狀態3)
整個效果包含兩個階段: 淹沒 —— 從狀態1到狀態2。整個粉紅色的區域向上淹沒整個頁面 展開 —— 從狀態2到狀態3。當淹沒整個頁面后,從中間展開直至整個頁面3、整體布局
這兩個階段就是實際上就是通過兩部分動畫的依次執行來實現的,我們先來看看布局: <?xml version="1.0" encoding="utf-8"?> <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width= "match_parent"android:layout_height= "match_parent" ><RelativeLayoutandroid:id="@+id/animation_content"android:layout_width="match_parent"android:layout_height="300dp"android:layout_gravity="bottom"><ImageViewandroid:layout_width="match_parent"android:layout_height="match_parent"android:src="@drawable/girl1"/><FrameLayoutandroid:id="@+id/spread_view"android:layout_width="match_parent"android:layout_height="0dp"android:layout_centerInParent="true" /><TextViewandroid:layout_width="match_parent"android:layout_height="match_parent"android:layout_above="@id/spread_view"android:drawableBottom="@drawable/camera_top"android:background="#e07468" /><TextViewandroid:layout_width="match_parent"android:layout_height="match_parent"android:layout_below="@id/spread_view"android:drawableTop="@drawable/camera_bottom"android:background="#e07468" /></RelativeLayout > </FrameLayout>整個布局主要由四個部分組成:
- animation_content —— 這個就是整個粉色區域的部分。
- spread_view —— 這個是黑色區域的部分,一開始高度是0
- 兩個textview —— 中間的圓形button實際上由上下兩個獨立的部分組成的,而且這兩部分中間夾著spread_view(這么布局是為了第二階段的動畫,下面會詳細講解)
這里要注意,我們使用了textview而不是imageview來實現button的布局,是因為如果使用imageview,當第二階段展開到button的兩部分超出屏幕頂部和底部時,imageview中的圖片會被縮小而不是溢出,差別如下
使用ImageView的效果
使用TextView的效果 所以我們這里使用TextView。并通過drawableBottom等屬性來設置圖片,這樣當區域縮小時,圖片大小并不會改變。4、源碼解析
下面就是實現的代碼: class?FloodAndSpreadActivity?:?Activity()?{override?fun?onCreate(savedInstanceState:?Bundle?)?{super.onCreate(savedInstanceState)setContentView(R.layout.flood_and_spread_activity)init()}fun?init(){val?height:?Int?=?window.windowManager.defaultDisplay.heightvar?floodWrapper?=?ViewWrapper(animation_content)var?spreadWrapper?=?ViewWrapper(spread_view)var?floodAnimation?=?ObjectAnimator.ofInt(floodWrapper,?"height",?height)floodAnimation.duration?=?1000floodAnimation.start()floodAnimation.addListener(object:?Animator.AnimatorListener{override?fun?onAnimationRepeat(p0:?Animator?)?{}override?fun?onAnimationCancel(p0:?Animator?)?{}override?fun?onAnimationStart(p0:?Animator?)?{}override?fun?onAnimationEnd(p0:?Animator?)?{ObjectAnimator.ofInt(spreadWrapper,?"height",?height).setDuration(1000).start()}})}class?ViewWrapper?(var?mTarget:?View){fun?getHeight():Int{return?mTarget.layoutParams.height}fun?setHeight(height:?Int){mTarget.layoutParams.height?=?heightmTarget.requestLayout()}} }Kotlin的一個優點就是能夠大量的簡化代碼,可以看到只用十幾行就實現了這個效果。
回到代碼本身,我們通過上面的分析知道整個過程由兩部分動畫組成:淹沒和展開。
在代碼中可以看到淹沒動畫floodAnimation,它通過floodWrapper來動態改變animation_content的高度直至屏幕高度,這樣就實現了淹沒的效果。而且由于spread_view設置成了centerInParent,而button的兩個部分與spread_view關聯,所以在這個動畫過程中button會跟隨著一起移動并始終處于animation_content中心。
5、知識點總結
ObjectAnimator
這里簡單說說我們用到的方法:ofInt(floodWrapper, "height", height)。這個方法主要針對int類型的參數。第一個參數是要改變屬性的類,可以是代理類,下面會講到;第二個參數是要改變的屬性名,實際上是調用類的對應的getter和setter方法;第三個參數是屬性的最終值,整個動畫過程中改屬性會從當前的值逐漸改變至最終值。
ObjectAnimator還有很多方法,大家有興趣可以自行學習。
ViewWrapper
這里要先說一說floodWrapper,它是一個ViewWrapper對象。ObjectAnimator會通過getter和setter方法來改變類某個屬性的值,但是如果沒有對應的方法或者需要更多的操作,我們可以使用代理的形式,ViewWrapper就是一個代理類。由于View只有getHeight函數沒有setHeight函數,所以我們使用ViewWrapper代理它并實現getHeight和setHeight函數。
再回到floodAnimation,我們看到有一個監聽器,當動畫結束的時候開始了另外一個動畫。動畫的這種關聯行為也可以使用另外一種方式:AnimatorSet,通過AnimatorSet可以實現多個動畫的不同順序的執行,處理復雜的動畫效果非常有用。由于本篇只是一個簡單的順序執行就沒有使用,關于AnimatorSet的使用比較簡單,大家可以查閱官方文檔。
在floodAnimation完成時我們執行了另外一個動畫,這就是第二個階段:展開。這次我們改變的是spread_view的高度,由于button的兩個部分是與spread_view關聯的,所以當spread_view高度改變時,button的兩個部分也隨著分離開,這樣就形成了展開的效果,直到spread_view展開到整個屏幕。
這樣這個效果就完成了,這個效果實際的應用是一個過渡或者過場動畫。主要的知識點就是屬性動畫的使用。
大家有興趣可以自己手動實現一下,對這兩個功能有更深入的了解。
源碼:
關注公眾號:BennuCTech,發送“FastWidget”獲取完整源碼
總結
以上是生活随笔為你收集整理的Android魔法(第二弹)——一步步实现淹没、展开效果的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 剖析Picasso加载压缩本地图片流程(
- 下一篇: android sina oauth2.