關於android幀動畫沒有提供結束播放的接口回調錶示不理解,也許是基於播放動畫的時候,系統在幹其他事情,無法確切地保證動畫在totalDuration時間內播放完畢等。如果有哪位前輩知道原因,請不吝指教。
儘管android沒有爲幀動畫提供結束播放的接口,我們還是可以通過一些其他方式來做到。
方式一,當動畫開始start之後,我們可以通過檢測是否到達幀動畫的最後一幀,來確定動畫是否播完。這種方式可以保證動畫播完。
方式二,重寫AnimationDrawable,獲得totalDuration,然後動畫start之後的totalDuration,調用結束的接口回調onAnimationFinshed()。爲什麼必須重寫呢?因爲,AnimationDrawable僅提供了每一幀的duration,而不能直接獲得動畫總的duration。
當然還有一些變種的方法,但是其大體思路都應該差不多。至於動畫是否流暢播放,這要取決於你播放動畫的時候,系統的繁忙程度。
下面給出例子:
定義幀動畫:
res/anim/effect_animation.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
<? xml
version = "1.0"
encoding = "utf-8" ?> < animation-list
android:oneshot = "true"
xmlns:android = "http://schemas.android.com/apk/res/android" >
< item
android:duration = "0"
android:drawable = "@drawable/curtain_5"
/> < item
android:duration = "0"
android:drawable = "@drawable/curtain_4"
/> < item
android:duration = "0"
android:drawable = "@drawable/curtain_3"
/> < item
android:duration = "0"
android:drawable = "@drawable/curtain_2"
/> < item
android:duration = "200"
android:drawable = "@drawable/curtain_0"
/> < item
android:duration = "0"
android:drawable = "@drawable/curtain_2"
/> < item
android:duration = "0"
android:drawable = "@drawable/curtain_3"
/> < item
android:duration = "0"
android:drawable = "@drawable/curtain_4"
/> < item
android:duration = "0"
android:drawable = "@drawable/curtain_5"
/> </ animation-list > |
思路一:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
|
private
void
checkIfAnimationDone() { mHandler.postDelayed( new
Runnable() { public
void
run() { if
(mAnimationDrawable.getCurrent() != mAnimationDrawable .getFrame(mAnimationDrawable.getNumberOfFrames()
- 1 ))
{ checkIfAnimationDone(); }
else
{ mHandler.sendEmptyMessage(MSG_ANIMATION_FINISHED); } } },
mDuration); }; private
void
playAnimation() { if
(mView == null )
{ mView
= mContext.getView(); } mView.setBackgroundResource(R.anim.effect_animation); mAnimationDrawable
= (AnimationDrawable) mView.getBackground(); mAnimationDrawable.start(); for
( int
i = 0 ;
i < mAnimationDrawable.getNumberOfFrames(); i++) { mDuration
+= mAnimationDrawable.getDuration(i); } checkIfAnimationDone(); } private
class
MainHandler extends
Handler { @Override public
void
handleMessage(Message msg) { if
(LOG) { Log.v(TAG,
"msg
id="
+ msg.what); } switch
(msg.what) { case
MSG_ANIMATION_FINISHED: if (mView
== null )
{ break ; } mView.setBackgroundResource( 0 ); break ; default : break ; } } } |
思路二:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
|
The
custom animation drawable class : public
abstract
class
CustomAnimationDrawableNew extends
AnimationDrawable { //
Handles the animation callback. Handler
mAnimationHandler; public
CustomAnimationDrawableNew(AnimationDrawable aniDrawable) { //
Add each frame to our animation drawable for
( int
i = 0 ;
i < aniDrawable.getNumberOfFrames(); i++) { this .addFrame(aniDrawable.getFrame(i),
aniDrawable.getDuration(i)); } } @Override public
void
start() { super .start(); /* *
Call super.start() to call the base class start animation method. *
Then add a handler to call onAnimationFinish() when the total *
duration for the animation has passed */ mAnimationHandler
= new
Handler(); mAnimationHandler.postDelayed( new
Runnable() { public
void
run() { onAnimationFinish(); } },
getTotalDuration()); } /** *
Gets the total duration of all frames. *
*
@return The total duration. */ public
int
getTotalDuration() { int
iDuration = 0 ; for
( int
i = 0 ;
i < this .getNumberOfFrames();
i++) { iDuration
+= this .getDuration(i); } return
iDuration; } /** *
Called when the animation finishes. */ public
abstract
void
onAnimationFinish(); } Use
this
class : ImageView
iv = (ImageView) findViewById(R.id.iv_testing_testani); iv.setOnClickListener( new
OnClickListener() { public
void
onClick( final
View v) { //
Pass our animation drawable to our custom drawable class CustomAnimationDrawableNew
cad = new
CustomAnimationDrawableNew( (AnimationDrawable)
getResources().getDrawable( R.drawable.anim_test))
{ @Override public
void
onAnimationFinish() { //
Animation has finished... } }; //
Set the views drawable to our custom drawable v.setBackgroundDrawable(cad); //
Start the animation cad.start(); } }); |