Android動畫三部曲之一 View Animation & LayoutAnimation
本篇文章對android的Tween動畫和幀動畫以及佈局動畫進行總結。
Tween動畫
Tween動畫又稱補間動畫。通過對view的位置、大小、透明度、角度的改變來實現動畫效果。
補間動畫的基類是Animation。我們通常使用它的直接子類RotateAnimation、TranslateAnimation、ScaleAnimation、AlphaAnimation。
補間動畫可以通過xml進行定義(res/anim/xxx),然後通過AnimationUtils類進行載入;也可以通過完全程式碼進行設定。
XML語法介紹
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="@[package:]anim/interpolator_resource"
android:shareInterpolator=["true" | "false"] >
<alpha
android:fromAlpha="float"
android:toAlpha="float" />
<scale
android:fromXScale ="float"
android:toXScale="float"
android:fromYScale="float"
android:toYScale="float"
android:pivotX="float"
android:pivotY="float" />
<translate
android:fromXDelta="float"
android:toXDelta="float"
android:fromYDelta="float"
android:toYDelta ="float" />
<rotate
android:fromDegrees="float"
android:toDegrees="float"
android:pivotX="float"
android:pivotY="float" />
<set>
...
</set>
</set>
Animation類定義了很多常量和變數的初始值,比如:
public static final int INFINITE = -1;
public static final int RESTART = 1;
public static final int REVERSE = 2;
主要用到它的子類以及AnimationListener :
public static interface AnimationListener {
/**
* 動畫開始的時候回撥
*
* @param animation The started animation.
*/
void onAnimationStart(Animation animation);
/**
* 動畫結束的時候回撥。但是當設定動畫重複次數為INFINITE的時候,該方法不會回撥。
*
* @param animation The animation which reached its end.
*/
void onAnimationEnd(Animation animation);
/**
* 動畫重複播放的時候回撥
*
* @param animation The animation which was repeated.
*/
void onAnimationRepeat(Animation animation);
}
新增此監聽器可以對動畫做更多的操作。
插值器 – Interpolator
介紹動畫之前,得先說說”插值器”。插值器的意思就是在播放動畫的時候,改變播放的速率,可以使動畫越來越快,或者越來越慢等。
常用的是一下九個插值器:
Baseinterpolator子類 | Resource ID | 描述 |
---|---|---|
AccelerateInterpolator | @android:anim/accelerate_interpolator | 加速變化(開始慢,越來越快) |
DecelerateInterpolator | @android:anim/decelerate_interpolator | 減速變化(開始快,越來越慢) |
AccelerateDecelerateInterpolator | @android:anim/accelerate_decelerate_interpolator | 先加速後減速(中間速度最快) |
LinearInterpolator | @android:anim/linear_interpolator | 線性均勻變化 |
OvershootInterpolator | @android:anim/overshoot_interpolator | 超出結尾的臨界值,然後在緩慢回到結束值 |
AnticipateInterpolator | @android:anim/anticipate_interpolator | 先向相反的方向改變一點,然後在加速播放 |
AnticipateOvershootInterpolator | @android:anim/anitcipate_overshoot_interpolator | 先向相反的方向改變一點,然後在加速播放至超出結束值一點,然後在緩慢回到結束值 |
BounceInterpolator | @android:anim/bounce_interpolator | 動畫快結束的時候,模擬球落地的回彈效果 |
CycleInterpolator | @android:anim/cycle_interpolator | 動畫迴圈播放指定的次數 |
自定義Interpolator
一般來說,官方API給的這幾個插值器就夠實用了。不過還可以自定義Interpolator。可以簡單的對系統的插值器進行一些引數值的修改:
<?xml version="1.0" encoding="utf-8"?>
<InterpolatorName xmlns:android="http://schemas.android.com/apk/res/android"
android:attribute_name="value" />
這裡推薦大家一個第三方的Interpolator庫:
公共XML屬性及對應的方法
屬性名稱 | 對應的方法 | 描述 |
---|---|---|
android:duration | setDuration(long) | 動畫持續的時間長度(單位是miliseconds) |
android:interpolator | setInterpolator(Interpolator) | 設定動畫播放時的插值器 |
android:repeatCount | setRepeatCount(int) | 設定動畫播放重複次數 |
android:repeatMode | setRepeatMode(int) | 設定動畫重複的方式(當repeat count>0時才有效) “reverse“(2) or “restart“(1) |
android:startOffset | setStartOffset(long) | 設定動畫開始播放的延遲時間 |
android:fillAfter | setFillAfter(boolean) | 設定為true時,檢視會停留在動畫結束的狀態。 |
android:fillBefore | setFillBefore(boolean) | 預設值是true,檢視會停留在動畫開始的狀態 |
android:fillEnable | setFillEnable(boolean) | 預設值是false。如果是true,動畫將會應用fillBefore值;否則,fillBefore的值會被忽略,transformation會在動畫結束的時候被應用。 |
android:detachWallpaper | setDetachWallpaper(boolean) | 預設值是false。如果為true,並且動畫窗體有一個桌布的話,那麼動畫只會應用給window,牆紙是靜態不動的 |
android:zAdjustment | setZAdjustment(int) | 允許在動畫播放期間,調整播放內容在Z軸方向的順序。”top“(1) or “normal“(0) or “bottom“(-1) |
android:zAdjustment:允許在動畫播放期間,調整播放內容在Z軸方向的順序:
- normal(0):正在播放的動畫內容保持當前的Z軸順序,
- top(1):在動畫播放期間,強制把當前播放的內容放到其他內容的上面;
- bottom(-1):在動畫播放期間,強制把當前播放的內容放到其他內容之下
ScaleAnimation – 縮放動畫
XML屬性名稱 | 描述 |
---|---|
android:fromXScale | 動畫起始時,X軸座標的伸縮尺寸。0.0表示收縮到沒有。1.0表示正常沒伸縮。>1.0表示放大。<1.0表示收縮。 |
android:toXScale | 動畫結束時X軸座標的伸縮尺寸 |
android:fromYScale | 動畫起始時Y軸座標的伸縮尺寸 |
android:toYScale | 動畫結束時Y軸座標的伸縮尺寸 |
android:pivotX | 縮放動畫作用點在X軸方向上的位置。android:pivotX=”50”表示絕對定位,相對於零點偏移50 –> Animation.ABSOLUTE android:pivotX=”50%”表示相對控制元件本身 –> Animation.RELATE_TO_SELF android:pivotX=”50%p”表示相對控制元件的父控制元件 –> Animation.RELATE_TO_PARENT |
android:pivotY | 縮放動畫作用點在Y軸方向上的位置 |
xml定義縮放動畫
<?xml version="1.0" encoding="utf-8"?>
<scale xmlns:android="http://schemas.android.com/apk/res/android"
android:background="@color/blue_light"
android:duration="1000"
android:fillAfter="false"
android:fillBefore="true"
android:fromXScale="1"
android:fromYScale="1"
android:interpolator="@android:anim/accelerate_decelerate_interpolator"
android:pivotX="50%"
android:pivotY="50%"
android:repeatCount="1"
android:repeatMode="restart"
android:startOffset="500"
android:toXScale="0"
android:toYScale="0"
android:zAdjustment="bottom" />
然後通過AnimationUtils類裝載動畫,進行應用。
Animation scaleAnimation = AnimationUtils.loadAnimation(this, R.anim.scale_anim);
targetIv.startAnimation(scaleAnimation);
程式碼定義縮放動畫
ScaleAnimation scaleAnimation = new ScaleAnimation(1.0f, 0.5f, 1.0f, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
scaleAnimation.setDuration(1000);
scaleAnimation.setInterpolator(new OvershootInterpolator());
scaleAnimation.setFillAfter(true);
targetIv.startAnimation(scaleAnimation);
ScaleAnimation有4個構造方法。
public ScaleAnimation(Context context, AttributeSet attrs) {}
public ScaleAnimation(float fromX, float toX, float fromY, float toY) {}
public ScaleAnimation(float fromX, float toX, float fromY, float toY, float pivotX, float pivotY) {}
public ScaleAnimation(float fromX, float toX, float fromY, float toY, int pivotXType, float pivotXValue, int pivotYType, float pivotYValue) {}
第一個構造用於從資原始檔中載入資源。我們主要用後三個。後面三個構造的區別就在設定變換中軸點與否。不指定pivotXType和pivotYType的話,預設採用ABSOLUTE形式,pivotX與pivotY的值都是相對於(0,0)左上角偏移的。
pivotXType可設定的引數有三種:ABSOLUTE、RELATE_TO_SELF、RELATE_TO_PARENT。
- ABSOLUTE表示當前設定的pivotX和pivotY值是絕對值,相對於左上角偏移。比如:android:pibotX=”50”
- RELATE_TO_SELF表示設定的pivotX和pivotY是相對值。比如:android:pivotX = “50%”表示X方向中軸點在正中間。 取值範圍是[0% ~ 100%]
- RELATE_TO_PARENT也是表示相對值,是相對於該檢視的父控制元件而言。比如:android:pivotX = “50%p”表示X方向中軸點是其父控制元件的中間位置。取值範圍是[0% ~ 100%]
效果如下:
RotateAnimation – 旋轉動畫
XML屬性名稱 | 描述 |
---|---|
android:fromDegrees | 動畫起始的角度(可正可負) |
android:toDegrees | 動畫終止的角度(可正可負) |
android:pivotX | 旋轉作用點在X軸方向上的位置。android:pivotX=”50”表示絕對定位,相對於零點偏移50 android:pivotX=”50%”表示相對控制元件本身 android:pivotX=”50%p”表示相對控制元件的父控制元件 |
android:pivotY | 旋轉作用點在Y軸方向上的位置 |
xml中設定旋轉動畫
<?xml version="1.0" encoding="utf-8"?>
<rotate xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="2500"
android:fillAfter="true"
android:fromDegrees="-20"
android:interpolator="@android:anim/overshoot_interpolator"
android:pivotX="50%"
android:pivotY="50%"
android:toDegrees="320" />
程式碼中設定旋轉動畫
RotateAnimation rotateAnimation = new RotateAnimation(0.0f, 550.0f, Animation.RELATIVE_TO_SELF, 0.3f, Animation.RELATIVE_TO_SELF, 0.3f);
rotateAnimation.setDuration(1500);
rotateAnimation.setInterpolator(new OvershootInterpolator());
rotateAnimation.setFillAfter(true);
targetIv.startAnimation(rotateAnimation);
效果圖如下:
TranslateAnimation – 平移動畫
XML屬性名稱 | 描述 |
---|---|
android:fromXDelta | 平移動畫起始位置X軸座標 |
android:toXDelta | 平移動畫結束位置X軸座標 |
android:fromYDelta | 平移動畫起始位置Y軸座標 |
android:toYDelta | 平移動畫結束位置Y軸座標 |
xml中設定平移動畫:
<?xml version="1.0" encoding="utf-8"?>
<translate xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="1000"
android:fromXDelta="0"
android:fromYDelta="0"
android:interpolator="@android:anim/anticipate_overshoot_interpolator"
android:toXDelta="50%p"
android:toYDelta="50%p" />
程式碼中設定平移動畫
TranslateAnimation translateAnimation = new TranslateAnimation(0, 200, 0, 0);
translateAnimation.setDuration(1000);
translateAnimation.setInterpolator(new AnticipateOvershootInterpolator());
targetIv.startAnimation(translateAnimation);
AlphaAnimation – 漸變動畫
XML屬性名稱 | 描述 |
---|---|
android:fromAlpha | 動畫開始時操作物件的alpha值 |
android:toAlpha | 動畫終止時操作物件的alpha值 |
xml中設定漸變動畫:
<?xml version="1.0" encoding="utf-8"?>
<alpha xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="1000"
android:fromAlpha="1.0"
android:interpolator="@android:anim/linear_interpolator"
android:repeatCount="1"
android:repeatMode="reverse"
android:toAlpha="0.0" />
程式碼中設定漸變動畫:
AlphaAnimation alphaAnimation = new AlphaAnimation(1.0f, 0.2f);
alphaAnimation.setDuration(1500);
alphaAnimation.setInterpolator(new AccelerateDecelerateInterpolator());
alphaAnimation.setRepeatMode(Animation.REVERSE);
alphaAnimation.setRepeatCount(1);
targetIv.startAnimation(alphaAnimation);
AnimationSet – 動畫集合
上面都是一個個的單獨的動畫,我們可以將很多個單獨的動畫組合到一起成為一個集合。
動畫集合也可以在xml中設定。需要用標籤包括其他簡單的動畫。比上述公共動畫屬性多了一個android:shareInterpolator=”boolean”,表示是否對子動畫設定相同的插值器。
xml中設定set動畫集合
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:fillAfter="true"
android:shareInterpolator="false">
<alpha
android:duration="1500"
android:fillAfter="true"
android:fromAlpha="1.0"
android:interpolator="@android:anim/accelerate_interpolator"
android:toAlpha="0.2" />
<scale
android:duration="1000"
android:fromXScale="0.8"
android:fromYScale="0.8"
android:interpolator="@android:anim/linear_interpolator"
android:pivotX="60%"
android:pivotY="20%"
android:startOffset="1500"
android:toXScale="0.3"
android:toYScale="0.5" />
<translate
android:duration="1000"
android:fromXDelta="0"
android:fromYDelta="0"
android:interpolator="@android:anim/bounce_interpolator"
android:startOffset="2500"
android:toXDelta="200"
android:toYDelta="200" />
<rotate
android:duration="1000"
android:fromDegrees="50"
android:interpolator="@android:anim/anticipate_overshoot_interpolator"
android:pivotX="50%p"
android:pivotY="50%p"
android:startOffset="3500"
android:toDegrees="360" />
</set>
我們來看一個現象:
設定了上面的set動畫之後,開始執行的時候,會發現漸變動畫開始執行的時候,會先變小,旋轉一個角度,然後才開始動畫。仔細分析xml程式碼之後,發現是在動畫開始的時候,把scale和rotate中的初始狀態給應用了。這時候想起了android:fillBefore屬性。
然後在scale、rotate 動畫裡添加了android:fillBefore=”false”屬性之後,發現還是不好使。檢視Animation類的原始碼發現,fillBefore必須在設定fillEnable=”true”的時候才神效。並且fillBefore的預設值是true,所以才會出現上述情況。
再次修改之後,程式碼如下:
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:fillAfter="true"
android:shareInterpolator="false">
<alpha
android:duration="1500"
android:fillAfter="true"
android:fromAlpha="1.0"
android:interpolator="@android:anim/accelerate_interpolator"
android:toAlpha="0.2" />
<scale
android:duration="1000"
android:fillBefore="false"
android:fillEnabled="true"
android:fromXScale="0.8"
android:fromYScale="0.8"
android:interpolator="@android:anim/linear_interpolator"
android:pivotX="60%"
android:pivotY="20%"
android:startOffset="1500"
android:toXScale="0.3"
android:toYScale="0.5" />
<translate
android:duration="1000"
android:fromXDelta="0"
android:fromYDelta="0"
android:interpolator="@android:anim/bounce_interpolator"
android:startOffset="2500"
android:toXDelta="200"
android:toYDelta="200" />
<rotate
android:duration="1000"
android:fillBefore="false"
android:fillEnabled="true"
android:fromDegrees="50"
android:interpolator="@android:anim/anticipate_overshoot_interpolator"
android:pivotX="50%p"
android:pivotY="50%p"
android:startOffset="3500"
android:toDegrees="360" />
</set>
效果如下:
Frame動畫
Frame動畫就是把圖片一幀一幀的播放出來的顯示效果,類似於gif圖片。幀動畫設定很簡單,只需要把每一幀對應的圖片按照順序新增進去,然後設定每一幀的顯示時長,然後為view控制元件設定該動畫,播放就行了。
xml設定幀動畫:
<?xml version="1.0" encoding="utf-8"?>
<animation-list xmlns:android="http://schemas.android.com/apk/res/android"
android:oneshot="false">
<item
android:drawable="@drawable/person1"
android:duration="100" />
<item
android:drawable="@drawable/person2"
android:duration="100" />
<item
android:drawable="@drawable/person3"
android:duration="100" />
<ite
android:drawable="@drawable/person4"
android:duration="100" />
<item
android:drawable="@drawable/person5"
android:duration="100" />
<item
android:drawable="@drawable/person6"
android:duration="100" />
<item
android:drawable="@drawable/person7"
android:duration="100" />
</animation-list>
給ImageView設定動畫:
targetIv.setBackgroundResource(R.drawable.frame_anim);
AnimationDrawable animationDrawable = (AnimationDrawable) targetIv.getBackground();
animationDrawable.start();
程式碼中設定幀動畫
AnimationDrawable animationDrawable = new AnimationDrawable();
animationDrawable.setOneShot(false);
animationDrawable.addFrame(getResources().getDrawable(R.drawable.person1), 200);
animationDrawable.addFrame(getResources().getDrawable(R.drawable.person2), 200);
animationDrawable.addFrame(getResources().getDrawable(R.drawable.person3), 200);
animationDrawable.addFrame(getResources().getDrawable(R.drawable.person4), 200);
animationDrawable.addFrame(getResources().getDrawable(R.drawable.person5), 200);
targetIv.setImageDrawable(animationDrawable);
animationDrawable.start();
LayoutAnimationController
Tween Animation和Frame Animation都是針對單個view操作的。而LayoutAnimationController可以針對一個ViewGroup進行動畫操作,可以讓一組view的每個view按照一定的規則展示動畫。
比如:可以針對listView、gridView或者recyclerView,定義item的出場動畫,而不是非常死板的一下子全顯示出來。
一般對ListView使用layoutAnimation動畫,對GridView使用gridLayoutAnimation動畫。對RecyclerView來說,正常情況下只能使用layoutAnimation動畫,應用gridLayoutAnimation動畫的時候會報錯。不錯可以針對RecyclerView生成一個子類做一下處理進行支援gridLayoutAnimation動畫。
xml屬性 | 對應的方法 | 描述 |
---|---|---|
android:delay | setDelay(float) | 動畫播放的延遲時間 |
android:animationOrder | setOrder(int) | 子view播放動畫的順序 [ normal |
android:interpolator | setInterpolator(Interpolator) setIntepolator(Context, @InterpolatorRes int) | 插值器 |
android:animation | LayoutAnimationController(animation) | 指定子view的動畫 |
xml定義LayoutAnimation
<?xml version="1.0" encoding="utf-8"?>
<layoutAnimation xmlns:android="http://schemas.android.com/apk/res/android"
android:animation="@anim/item_list_anim"
android:animationOrder="normal"
android:delay="0.2"
android:interpolator="@android:anim/bounce_interpolator" />
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="1000"
android:shareInterpolator="true">
<alpha
android:fromAlpha="0.0"
android:toAlpha="1.0" />
<translate
android:fromXDelta="-100%"
android:toXDelta="0%" />
</set>
程式碼中定義LayoutAnimation
public LayoutAnimationController(Animation animation) {
this(animation, 0.5f);
}
public LayoutAnimationController(Animation animation, float delay) {
mDelay = delay;
setAnimation(animation);
}
LayoutAnimationController有三個建構函式,常用的時候上面兩個。delay表示每個子view啟動動畫的延遲時間,預設是0.5f。delay以秒為單位 。
Animation animation = AnimationUtils.loadAnimation(this, R.anim.item_list_anim);
LayoutAnimationController layoutAnimationController = new LayoutAnimationController(animation);
layoutAnimationController.setInterpolator(new AccelerateInterpolator());
layoutAnimationController.setDelay(0.5f);
layoutAnimationController.setOrder(LayoutAnimationController.ORDER_RANDOM);
recyclerView.setLayoutAnimation(layoutAnimationController);
GridLayoutAnimationController
GridLayoutAnimationController是LayoutAnimationController的子類。針對GridView做動畫操作。
xml屬性 | 對應的方法 | 描述 |
---|---|---|
android:delay | setDelay(float) | 動畫播放的延遲時間 |
android:columnDelay | setColumnDelay(float) | 列播放動畫的延遲時間 |
android:rowDelay | setRowDelay(float) | 行播放動畫的延遲時間 |
android:animationOrder | setOrder(int) | 子view播放動畫的順序 [ normal |
android:animation | LayoutAnimationController(animation) | 指定子view的動畫 |
xml中定義
<GridView
android:id="@+id/test_grid_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:columnWidth="60dp"
android:gravity="center"
android:horizontalSpacing="10dp"
android:layoutAnimation="@anim/grid_layout_anim"
android:numColumns="3"
android:padding="10dp"
android:scrollbars="none"
android:stretchMode="columnWidth"
android:verticalSpacing="10dp" />
<?xml version="1.0" encoding="utf-8"?>
<gridLayoutAnimation xmlns:android="http://schemas.android.com/apk/res/android"
android:animation="@anim/item_anim_alpha"
android:columnDelay="0.5"
android:direction="bottom_to_top|right_to_left"
android:directionPriority="row" />
<?xml version="1.0" encoding="utf-8"?>
<alpha xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="500"
android:fromAlpha="0.0"
android:interpolator="@android:anim/accelerate_interpolator"
android:toAlpha="1.0" />
程式碼中設定
同樣是使用一個Animation構造出GridLayoutAnimation物件,然後設定各種引數,最後設定此動畫GridView即可。
Animation animation = AnimationUtils.loadAnimation(this, R.anim.item_anim_alpha);
GridLayoutAnimationController gridLayoutAnimationController = new GridLayoutAnimationController(animation);
gridLayoutAnimationController.setDirection(GridLayoutAnimationController.DIRECTION_BOTTOM_TO_TOP | GridLayoutAnimationController.DIRECTION_RIGHT_TO_LEFT);
gridLayoutAnimationController.setDirectionPriority(GridLayoutAnimationController.PRIORITY_ROW);
gridRecyclerView.setLayoutAnimation(gridLayoutAnimationController);
效果如下:
RecyclerView擴充套件
正常情況下,我們可以對RecyclerView使用LayoutAnimation動畫。但是如果對RecycleView使用動畫的時候出現以下錯誤:
AndroidRuntime: FATAL EXCEPTION: main
Process: com.jacksen.demo.view, PID: 30770
java.lang.ClassCastException: android.view.animation.LayoutAnimationController$AnimationParameters cannot be cast to android.view.animation.GridLayoutAnimationController$AnimationParameters
at android.view.animation.GridLayoutAnimationController.getDelayForView(GridLayoutAnimationController.java:299)
at android.view.animation.LayoutAnimationController.getAnimationForView(LayoutAnimationController.java:321)
at android.view.ViewGroup.bindLayoutAnimation(ViewGroup.java:3717)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2892)
......
意思就是GridLayoutAnimationController.AnimationParameters不能強轉成LayoutAnimationController.AnimationParameters。
RecyclerView的出現本來就是替代Listview的,但是它有可以展示出GridView的效果,但是怎麼讓RecyclerView設定GridLayoutManager的時候應用gridLayoutAnimation動畫呢?
我們先來看看Gridview怎麼實現的?
在GridView原始碼裡面搜尋”LayoutAnimation”關鍵字發現,只有一個attachLayoutAnimationParameters()的函式,裡面將layoutAnimationParameters強轉成GridLayoutAnimationController.AnimationParameters。
@Override
protected void attachLayoutAnimationParameters(View child,
ViewGroup.LayoutParams params, int index, int count) {
GridLayoutAnimationController.AnimationParameters animationParams =
(GridLayoutAnimationController.AnimationParameters) params.layoutAnimationParameters;
if (animationParams == null) {
animationParams = new GridLayoutAnimationController.AnimationParameters();
params.layoutAnimationParameters = animationParams;
}
animationParams.count = count;
animationParams.index = index;
animationParams.columnsCount = mNumColumns;
animationParams.rowsCount = count / mNumColumns;
if (!mStackFromBottom) {
animationParams.column = index % mNumColumns;
animationParams.row = index / mNumColumns;
} else {
final int invertedIndex = count - 1 - index;
animationParams.column = mNumColumns - 1 - (invertedIndex % mNumColumns);
animationParams.row = animationParams.rowsCount - 1 - invertedIndex / mNumColumns;
}
}
然後就想到去RecyclerView中去找attachLayoutAnimationParameters()方法,但是沒有,其父類ViewGroup裡面有此方法:
protected void attachLayoutAnimationParameters(View child,
LayoutParams params, int index, int count) {
LayoutAnimationController.AnimationParameters animationParams =
params.layoutAnimationParameters;
if (animationParams == null) {
animationParams = new LayoutAnimationController.AnimationParameters();
params.layoutAnimationParameters = animationParams;
}
animationParams.count = count;
animationParams.index = index;
}
由此可見RecyclerView預設實現了ViewGroup的LayoutAnimation。我們在RecyclerView中將此方法重寫一下。不過要將mStackFromButtom引數的判斷去掉。
public class GridRecyclerView extends RecyclerView {
public GridRecyclerView(Context context) {
super(context);
}
public GridRecyclerView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public GridRecyclerView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
@Override
public void setAdapter(Adapter adapter) {
super.setAdapter(adapter);
}
@Override
public void setLayoutManager(LayoutManager layout) {
if (layout instanceof GridLayoutManager) {
super.setLayoutManager(layout);
} else {
throw new ClassCastException("you should only use the GridLayoutManager as LayoutManager when you use this " + this.getClass().getSimpleName() + " class");
}
}
@Override
protected void attachLayoutAnimationParameters(View child, ViewGroup.LayoutParams params, int index, int count) {
if (getLayoutManager() != null && getLayoutManager() instanceof GridLayoutManager) {
GridLayoutAnimationController.AnimationParameters animationParams =
(GridLayoutAnimationController.AnimationParameters) params.layoutAnimationParameters;
if (animationParams == null) {
animationParams = new GridLayoutAnimationController.AnimationParameters();
params.layoutAnimationParameters = animationParams;
}
int mNumColumns = ((GridLayoutManager) getLayoutManager()).getSpanCount();
animationParams.count = count;
animationParams.index = index;
animationParams.columnsCount = mNumColumns;
animationParams.rowsCount = count / mNumColumns;
final int invertedIndex = count - 1 - index;
animationParams.column = mNumColumns - 1 - (invertedIndex % mNumColumns);
animationParams.row = animationParams.rowsCount - 1 - invertedIndex / mNumColumns;
} else {
super.attachLayoutAnimationParameters(child, params, index, count);
}
}
}
當我們使用GridLayoutManager的時候,不能使用此屬性。
/**
* stackFromEnd is not supported by GridLayoutManager. Consider using
* {@link #setReverseLayout(boolean)}.
*/
@Override
public void setStackFromEnd(boolean stackFromEnd) {
if (stackFromEnd) {
throw new UnsupportedOperationException(
"GridLayoutManager does not support stack from end."
+ " Consider using reverse layout");
}
super.setStackFromEnd(false);
}
此篇blog到此結束~
感謝大家支援!如有錯誤,請指出~
謝謝~
參考:
相關推薦
Android動畫三部曲之一 View Animation & LayoutAnimation
本篇文章對android的Tween動畫和幀動畫以及佈局動畫進行總結。 Tween動畫 Tween動畫又稱補間動畫。通過對view的位置、大小、透明度、角度的改變來實現動畫效果。 補間動畫的基類是Animation。我們通常使用它的直接子類R
Android動畫效果之Frame Animation(逐幀動畫)
想要 顯示 star 載體 rop 復雜 ide sources post 前言: 上一篇介紹了Android的Tween Animation(補間動畫) Android動畫效果之Tween Animation(補間動畫),今天來總結下Android的另外一種動
Android動畫控制元件之Animation
概述: android的動畫效果包括:移動,漸變透明度,旋轉,縮放。 實現動畫的方式有兩種:在java程式碼中動態實現,在xml中靜態實現。 demo 動態實現: /*
Android 動畫之補間動畫(View Animation)
Android 中補間動畫包括下面四種: 1.透明度動畫 (AlphaAnimation) 2.縮放動畫 (ScaleAnimation) 3.平移動畫 (TranslateAnimation) 4.旋轉動畫 (RotateAnimation) 補間動畫是專門針對V
Android三種動畫View Animation(補間動畫) 、Drawable Animation(幀動畫) 、Property Animation(屬性動畫)(下)
轉載:http://blog.csdn.net/lmj623565791/article/details/38092093 三種動畫的優缺點: (1)Frame Animation(幀動畫)主要用於播放一幀幀準備好的圖片,類似GIF圖片,優點是使用簡單
【Android 動畫】View Animation詳解(一)
安卓平臺目前提供了兩大類動畫,在Android 3.0之前,一大類是View Animation,包括Tween animation(補間動畫),Frame animation(幀動畫),在android3.0中又引入了一個新的動畫系統:property ani
Android-View Animation(檢視動畫)
Android系統提供了兩種動畫框架:property動畫(屬性動畫)和View動畫(檢視動畫)。這兩個動畫系統都是可行的方案,但在一般情況下,屬性動畫系統被優先使用,因為它更靈活,並且提供
Android 動畫學習(一)之View Animation
Android動畫初步 動畫(Animation)在我們日常的Android開發工作當中使用得較為頻繁,尤其對於Android遊戲這個動畫的集合體,掌握動畫開發的重要性毋庸置疑。同
android.view.animation(2) - 插值器Interpolator
tin logs lis png 16px tor 文件 anim near public interface Interpolator implements TimeInterpolator android.view.animation.Interpolator
【Android界面實現】View Animation 使用介紹
ref 轉載 HA ceshi 很多 ons 伸縮 ets 時間設置 ? ? 轉載請註明出處:http://blog.csdn.net/zhaokaiqiang19
Android動畫筆記之Animation
簡介 Android提供了兩種機制,您可以使用它們來建立簡單的動畫:補間動畫,您可以在其中告訴Android對檢視內容執行一系列簡單的轉換(位置,大小,旋轉等); 和逐幀動畫,一個接一個地載入一系列Drawable資源。 兩種動畫型別都可以在任何View物件中使用,以提供簡單的旋轉計
android基礎--列表資料View重新整理動畫
該效果類似於iPhone中View的切換動畫效果 效果一: 效果二: 效果三: 效果四: 效果五(迴旋效果一): 效果六(迴旋效果二): 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
Android動畫精講一 從setTranslationX談屬性動畫和view動畫的區別
最近又用到了動畫,決定把幾次專案裡用到的動畫走過的彎路總結一下,順便梳理下android的動畫體系。眾所周知,android動畫分三類:一是View 動畫,又叫Tween動畫,二是frame 動畫(幀動畫),又叫drawable 動畫,三是屬性動畫,即p
android進階4step1:Android動畫處理與自定義View——SurfaceView
SurfaceView簡介 1、SurfaceView與View的區別 2、SurfaceView的具體使用場景 3、如何使用SurfaceView 一、SurfaceView與View的區別 1、不使用onDraw 2、非UI執行緒繪製 3、獨立
android進階4step1:Android動畫處理與自定義View——自定義View
為什麼要自定義控制元件 特定的顯示風格 處理特有的使用者互動 優化我們的佈局 封裝等... 如何自定義控制元件 自定義屬性的宣告與獲取 測量onMeasure 繪製onDraw 狀態的儲存與恢復 步驟一、自定義屬性宣告與獲取
android進階4step1:Android動畫處理與自定義View——轉場動畫
以下都需要執行在5.0以上 一、揭露動畫效果 參考:使用Circular Reveal為你的應用新增揭露動畫效果 最主要的類Circular Reveal 官方將這一動畫稱為揭露效果,它在官網中的描述是這樣的: 當您顯示或隱藏一組 UI 元素時,揭露動畫可為使用者提供視覺
Android 有點選動畫效果的View
Bitmap extractAlpha () Returns a new bitmap that captures the alpha values of the original. This may be drawn with Canvas.drawBitmap(), where the color(s
程式碼藝術-Android針對帶有複雜動畫自定義view的程式碼設計
Android自定義view有時需要完成一些複雜的動畫,這時後會發現程式碼看起來還是蠻複雜的,如何實現讓程式碼結構清晰,對提供程式碼穩定性以及對程式碼修改有著非常大的幫助。下面是我提供的一種思路。 思路原理: 我們知道一個動畫其實是有固定流程的,比如一個走動的
詳解Android動畫之Tween Animation
轉載地址:http://blog.csdn.net/liuhe688/article/details/6660823 前面講了動畫中的Frame動畫,今天就來詳細講解一下Tween動畫的使用。 同樣,在開始例項演示之前,先引用官方文件中的一段話:
Android動畫-Frame Animation(幀動畫)
Android動畫主要分為以下三類: Tweened animation(補間動畫)- 在android3.0(API11)之前支援,該動畫僅僅支援對View操作,而且View在做動畫的時候,View相應的實際屬性值並沒有發生改變,例如:一個Button起始位置left,to