前Android物业动画研究(Property Animation)全然解析具体解释上已经基本展示了属性动画的核心使用方法:
ObjectAnimator实现动画,ValueAnimator实现动画,AnimatorSet的使用等~
当然了属性动画另一部分的知识点,也能做出非常不错的效果,将在本篇博客为您展示~
大家肯定都清楚,View Animator 、Drawable Animator都能够在anim目录下创建动画,然后在程序中使用,甚至在Theme中设置为属性值。当然了。属性动画事实上也能够在文件里声明:
首先在res下建立animator目录。然后建立res/animator/scalex.xml
1
2
3
4
5
6
7
8
|
<?
xml
version
=
"1.0"
encoding
=
"utf-8"
?
>
<
objectAnimator
xmlns
:
android
=
"http://schemas.android.com/apk/res/android"
android
:
duration
=
"1000"
android
:
propertyName
=
"scaleX"
android
:
valueFrom
=
"1.0"
android
:
valueTo
=
"2.0"
android
:
valueType
=
"floatType"
>
<
/
objectAnimator
>
|
代码:
1
2
3
4
5
6
7
|
public
void
scaleX
(
View
view
)
{
// 载入动画
Animator
anim
=
AnimatorInflater
.
loadAnimator
(
this
,
R
.
animator
.
scalex
)
;
anim
.
setTarget
(
mMv
)
;
anim
.
start
(
)
;
}
|
使用AnimatorInflater载入动画的资源文件,然后设置目标,就ok~~是不是非常easy,这仅仅是单纯横向的放大一倍~
假设我希望纵向与横向同一时候缩放呢?则能够怎么定义属性文件:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
<?
xml
version
=
"1.0"
encoding
=
"utf-8"
?
>
<
set
xmlns
:
android
=
"http://schemas.android.com/apk/res/android"
android
:
ordering
=
"together"
>
<
objectAnimator
android
:
duration
=
"1000"
android
:
propertyName
=
"scaleX"
android
:
valueFrom
=
"1"
android
:
valueTo
=
"0.5"
>
<
/
objectAnimator
>
<
objectAnimator
android
:
duration
=
"1000"
android
:
propertyName
=
"scaleY"
android
:
valueFrom
=
"1"
android
:
valueTo
=
"0.5"
>
<
/
objectAnimator
>
<
/
set
>
|
使用set标签,有一个orderring属性设置为together,【还有还有一个值:sequentially(表示一个接一个运行)】。
上篇博客中忽略了一个效果。就是缩放、反转等都有中心点或者轴,默认中心缩放,和中间对称线为反转线。所以我决定这个横向,纵向缩小以左上角为中心点:
代码:
1
2
3
4
5
6
7
8
|
// 载入动画
Animator
anim
=
AnimatorInflater
.
loadAnimator
(
this
,
R
.
animator
.
scale
)
;
mMv
.
setPivotX
(
0
)
;
mMv
.
setPivotY
(
0
)
;
//显示的调用invalidate
mMv
.
invalidate
(
)
;
anim
.
setTarget
(
mMv
)
;
anim
.
start
(
)
;
|
非常easy。直接给View设置pivotX和pivotY,然后调用一下invalidate,就ok了。
以下看效果图:
好了,通过写xml声明动画,使用set嵌套set。结合orderring属性,也基本能够实现不论什么动画~~上面也演示了pivot的设置。
主要使用LayoutTransition为布局的容器设置动画。当容器中的视图层次发生变化时存在过渡的动画效果。
基本代码为:
1
2
3
4
5
6
7
8
9
10
|
LayoutTransition
transition
=
new
LayoutTransition
(
)
;
transition
.
setAnimator
(
LayoutTransition
.
CHANGE_APPEARING
,
transition
.
getAnimator
(
LayoutTransition
.
CHANGE_APPEARING
)
)
;
transition
.
setAnimator
(
LayoutTransition
.
APPEARING
,
null
)
;
transition
.
setAnimator
(
LayoutTransition
.
DISAPPEARING
,
null
)
;
transition
.
setAnimator
(
LayoutTransition
.
CHANGE_DISAPPEARING
,
null
)
;
mGridLayout
.
setLayoutTransition
(
transition
)
;
|
过渡的类型一共同拥有四种:
LayoutTransition.APPEARING 当一个View在ViewGroup中出现时。对此View设置的动画
LayoutTransition.CHANGE_APPEARING 当一个View在ViewGroup中出现时。对此View对其它View位置造成影响。对其它View设置的动画
LayoutTransition.DISAPPEARING 当一个View在ViewGroup中消失时,对此View设置的动画
LayoutTransition.CHANGE_DISAPPEARING 当一个View在ViewGroup中消失时,对此View对其它View位置造成影响,对其它View设置的动画
LayoutTransition.CHANGE 不是因为View出现或消失造成对其它View位置造成影响,然后对其它View设置的动画。
注意动画究竟设置在谁身上,此View还是其它View。
好了以下看一个综合的样例:
布局文件:
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
|
<
LinearLayout
xmlns
:
android
=
"http://schemas.android.com/apk/res/android"
xmlns
:
tools
=
"http://schemas.android.com/tools"
android
:
id
=
"@+id/id_container"
android
:
layout_width
=
"match_parent"
android
:
layout_height
=
"match_parent"
android
:
orientation
=
"vertical"
>
<
Button
android
:
layout_width
=
"wrap_content"
android
:
layout_height
=
"wrap_content"
android
:
onClick
=
"addBtn"
android
:
text
=
"addBtns"
/
>
<
CheckBox
android
:
id
=
"@+id/id_appear"
android
:
layout_width
=
"wrap_content"
android
:
layout_height
=
"wrap_content"
android
:
checked
=
"true"
android
:
text
=
"APPEARING"
/
>
<
CheckBox
android
:
id
=
"@+id/id_change_appear"
android
:
layout_width
=
"wrap_content"
android
:
layout_height
=
"wrap_content"
android
:
checked
=
"true"
android
:
text
=
"CHANGE_APPEARING"
/
>
<
CheckBox
android
:
id
=
"@+id/id_disappear"
android
:
layout_width
=
"wrap_content"
android
:
layout_height
=
"wrap_content"
android
:
checked
=
"true"
android
:
text
=
"DISAPPEARING"
/
>
<
CheckBox
android
:
id
=
"@+id/id_change_disappear"
android
:
layout_width
=
"wrap_content"
android
:
layout_height
=
"wrap_content"
android
:
checked
=
"true"
android
:
text
=
"CHANGE_DISAPPEARING "
/
>
<
/
LinearLayout
>
|
代码:
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
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
|
package
com
.
example
.
zhy_property_animation
;
import
android
.
animation
.
LayoutTransition
;
import
android
.
app
.
Activity
;
import
android
.
os
.
Bundle
;
import
android
.
view
.
View
;
import
android
.
view
.
View
.
OnClickListener
;
import
android
.
view
.
ViewGroup
;
import
android
.
widget
.
Button
;
import
android
.
widget
.
CheckBox
;
import
android
.
widget
.
CompoundButton
;
import
android
.
widget
.
CompoundButton
.
OnCheckedChangeListener
;
import
android
.
widget
.
GridLayout
;
public
class
LayoutAnimaActivity
extends
Activity
implements
OnCheckedChangeListener
{
private
ViewGroup
viewGroup
;
private
GridLayout
mGridLayout
;
private
int
mVal
;
private
LayoutTransition
mTransition
;
private
CheckBox
mAppear
,
mChangeAppear
,
mDisAppear
,
mChangeDisAppear
;
@
Override
public
void
onCreate
(
Bundle
savedInstanceState
)
{
super
.
onCreate
(
savedInstanceState
)
;
setContentView
(
R
.
layout
.
layout_animator
)
;
viewGroup
=
(
ViewGroup
)
findViewById
(
R
.
id
.
id_container
)
;
mAppear
=
(
CheckBox
)
findViewById
(
R
.
id
.
id_appear
)
;
mChangeAppear
=
(
CheckBox
)
findViewById
(
R
.
id
.
id_change_appear
)
;
mDisAppear
=
(
CheckBox
)
findViewById
(
R
.
id
.
id_disappear
)
;
mChangeDisAppear
=
(
CheckBox
)
findViewById
(
R
.
id
.
id_change_disappear
)
;
mAppear
.
setOnCheckedChangeListener
(
this
)
;
mChangeAppear
.
setOnCheckedChangeListener
(
this
)
;
mDisAppear
.
setOnCheckedChangeListener
(
this
)
;
mChangeDisAppear
.
setOnCheckedChangeListener
(
this
)
;
// 创建一个GridLayout
mGridLayout
=
new
GridLayout
(
this
)
;
// 设置每列5个button
mGridLayout
.
setColumnCount
(
5
)
;
// 加入到布局中
viewGroup
.
addView
(
mGridLayout
)
;
//默认动画所有开启
mTransition
=
new
LayoutTransition
(
)
;
mGridLayout
.
setLayoutTransition
(
mTransition
)
;
}
/**
* 加入button
*
* @param view
*/
public
void
addBtn
(
View
view
)
{
final
Button
button
=
new
Button
(
this
)
;
button
.
setText
(
(
++
mVal
)
+
""
)
;
mGridLayout
.
addView
(
button
,
Math
.
min
(
1
,
mGridLayout
.
getChildCount
(
)
)
)
;
button
.
setOnClickListener
(
new
OnClickListener
(
)
{
@
Override
public
void
onClick
(
View
v
)
{
mGridLayout
.
removeView
(
button
)
;
}
}
)
;
}
@
Override
public
void
onCheckedChanged
(
CompoundButton
buttonView
,
boolean
isChecked
)
{
mTransition
=
new
LayoutTransition
(
)
;
mTransition
.
setAnimator
(
LayoutTransition
.
APPEARING
,
(
mAppear
.
isChecked
(
)
?
mTransition
.
getAnimator
(
LayoutTransition
.
APPEARING
)
:
null
)
)
;
mTransition
.
setAnimator
(
LayoutTransition
.
CHANGE_APPEARING
,
(
mChangeAppear
.
isChecked
(
)
?
mTransition
.
getAnimator
(
LayoutTransition
.
CHANGE_APPEARING
)
:
null
)
)
;
mTransition
.
setAnimator
(
LayoutTransition
.
DISAPPEARING
,
(
mDisAppear
.
isChecked
(
)
?
mTransition
.
getAnimator
(
LayoutTransition
.
DISAPPEARING
)
:
null
)
)
;
mTransition
.
setAnimator
(
LayoutTransition
.
CHANGE_DISAPPEARING
,
(
mChangeDisAppear
.
isChecked
(
)
?
mTransition
.
getAnimator
(
LayoutTransition
.
CHANGE_DISAPPEARING
)
:
null
)
)
;
mGridLayout
.
setLayoutTransition
(
mTransition
)
;
}
}
|
效果图:
动画有点长,耐心点看,一定要注意,是对当前View还是其它Views设置的动画。
当然了动画支持自己定义,还支持设置时间,比方我们改动下,加入的动画为:
1
2
3
|
mTransition
.
setAnimator
(
LayoutTransition
.
APPEARING
,
(
mAppear
.
isChecked
(
)
?
ObjectAnimator.ofFloat(this, "scaleX", 0, 1)
:
null
)
)
;
|
则效果为:
原本的淡入,变成了宽度从中间放大的效果~~是不是还不错~~
在SDK11的时候。给View加入了animate方法,更加方便的实现动画效果。
布局文件:
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
|
<
RelativeLayout
xmlns
:
android
=
"http://schemas.android.com/apk/res/android"
xmlns
:
tools
=
"http://schemas.android.com/tools"
android
:
layout_width
=
"match_parent"
android
:
layout_height
=
"match_parent"
>
<
ImageView
android
:
id
=
"@+id/id_ball"
android
:
layout_width
=
"wrap_content"
android
:
layout_height
=
"wrap_content"
android
:
src
=
"@drawable/bol_blue"
/
>
<
LinearLayout
android
:
layout_width
=
"fill_parent"
android
:
layout_height
=
"wrap_content"
android
:
layout_alignParentBottom
=
"true"
android
:
orientation
=
"horizontal"
>
<
Button
android
:
layout_width
=
"wrap_content"
android
:
layout_height
=
"wrap_content"
android
:
onClick
=
"viewAnim"
android
:
text
=
"View Anim"
/
>
<
Button
android
:
layout_width
=
"wrap_content"
android
:
layout_height
=
"wrap_content"
android
:
onClick
=
"propertyValuesHolder"
android
:
text
=
"PropertyValuesHolder "
/
>
<
/
LinearLayout
>
<
/
RelativeLayout
>
|
代码:
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
|
package
com
.
example
.
zhy_property_animation
;
import
android
.
animation
.
ObjectAnimator
;
import
android
.
animation
.
PropertyValuesHolder
;
import
android
.
app
.
Activity
;
import
android
.
os
.
Bundle
;
import
android
.
util
.
DisplayMetrics
;
import
android
.
util
.
Log
;
import
android
.
view
.
View
;
import
android
.
widget
.
ImageView
;
public
class
ViewAnimateActivity
extends
Activity
{
protected
static
final
String
TAG
=
"ViewAnimateActivity"
;
private
ImageView
mBlueBall
;
private
float
mScreenHeight
;
@
Override
protected
void
onCreate
(
Bundle
savedInstanceState
)
{
super
.
onCreate
(
savedInstanceState
)
;
setContentView
(
R
.
layout
.
view_animator
)
;
DisplayMetrics
outMetrics
=
new
DisplayMetrics
(
)
;
getWindowManager
(
)
.
getDefaultDisplay
(
)
.
getMetrics
(
outMetrics
)
;
mScreenHeight
=
outMetrics
.
heightPixels
;
mBlueBall
=
(
ImageView
)
findViewById
(
R
.
id
.
id_ball
)
;
}
public
void
viewAnim
(
View
view
)
{
// need API12
mBlueBall
.
animate
(
)
//
.
alpha
(
0
)
//
.
y
(
mScreenHeight
/
2
)
.
setDuration
(
1000
)
// need API 12
.
withStartAction
(
new
Runnable
(
)
{
@
Override
public
void
run
(
)
{
Log
.
e
(
TAG
,
"START"
)
;
}
// need API 16
}
)
.
withEndAction
(
new
Runnable
(
)
{
@
Override
public
void
run
(
)
{
Log
.
e
(
TAG
,
"END"
)
;
runOnUiThread
(
new
Runnable
(
)
{
@
Override
public
void
run
(
)
{
mBlueBall
.
setY
(
0
)
;
mBlueBall
.
setAlpha
(
1.0f
)
;
}
}
)
;
}
}
)
.
start
(
)
;
}
}
|
简单的使用mBlueBall.animate().alpha(0).y(mScreenHeight / 2).setDuration(1000).start()就能实现动画~~只是须要SDK11,此后在SDK12,SDK16又分别加入了withStartAction和withEndAction用于在动画前。和动画后运行一些操作。当然也能够.setListener(listener)等操作。
使用ObjectAnimator实现上面的变化,我们能够使用:PropertyValueHolder
1
2
3
4
5
|
PropertyValuesHolder
pvhX
=
PropertyValuesHolder
.
ofFloat
(
"alpha"
,
1f
,
0f
,
1f
)
;
PropertyValuesHolder
pvhY
=
PropertyValuesHolder
.
ofFloat
(
"y"
,
0
,
mScreenHeight
/
2
,
0
)
;
ObjectAnimator
.
ofPropertyValuesHolder
(
mBlueBall
,
pvhX
,
pvhY
)
.
setDuration
(
1000
)
.
start
(
)
;
|
效果与上面一样。
执行结果:
好了,关于属性动画基本全部的使用方法到此结束~~~~欢迎大家一起学习,一起进步。
源代码下载:zhy_property_animation
版权声明:本文博客原创文章,博客,未经同意,不得转载。