MaterialDesign中的动画

在Android5.0(API Level 21)以后,可以使用Material Design(MD)中的动画可以给用户提供触摸反馈和一致性交互体验。Activity&Fragment过渡动画就是MD中动画的一种,接下来介绍MD中其它类型的动画。

Ripple Animation

MD大量使用了Ripple效果,即点击后View后,产生波纹效果,这个效果主要用于触摸反馈。

可以通过如下代码设置View的波纹背景:

1
2
3
4
5
// 有边界波纹
android:background="?android:attr/selectableItemBackground"

// 无边界波纹
android:foreground="?android:attr/selectableItemBackgroundBorderless"

如果要修改默认波纹的颜色,可以使用主题中android:colorControlHighlight属性进行设置。

还可以在XML文件中,直接创建Ripple效果的背景资源:

1
2
3
4
5
6
7
8
9
10
<?xml version="1.0" encoding="utf-8"?>
<!-- res/drawable/ripple_sample -->
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
android:color="@color/colorPrimary">
<item>
<shape android:shape="oval">
<solid android:color="@color/colorAccent"/>
</shape>
</item>
</ripple>

Reveal Animation

Reveal动画为显示或隐藏一组UI元素提供视觉一致性体验,具体表现为一个View以圆的形式展开。使用ViewAnimationUtils.createCircularReveal()方法创建Reveal动画。

展现隐藏的View:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// previously invisible view
View myView = findViewById(R.id.my_view);

// get the center for the clipping circle
int cx = myView.getWidth() / 2;
int cy = myView.getHeight() / 2;

// get the final radius for the clipping circle
float finalRadius = (float) Math.hypot(cx, cy);

// create the animator for this view (the start radius is zero)
Animator anim =
ViewAnimationUtils.createCircularReveal(myView, cx, cy, 0, finalRadius);

// make the view visible and start the animation
myView.setVisibility(View.VISIBLE);
anim.start();

隐藏可见的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
// previously visible view
final View myView = findViewById(R.id.my_view);

// get the center for the clipping circle
int cx = myView.getWidth() / 2;
int cy = myView.getHeight() / 2;

// get the initial radius for the clipping circle
float initialRadius = (float) Math.hypot(cx, cy);

// create the animation (the final radius is zero)
Animator anim =
ViewAnimationUtils.createCircularReveal(myView, cx, cy, initialRadius, 0);

// make the view invisible when the animation is done
anim.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
myView.setVisibility(View.INVISIBLE);
}
});

// start the animation
anim.start();

View State Changes Animation

在Android5.0以后,可以为View的状态改变设置一个状态切换动画。

StateListAnimator

StateListAnimator作为视图改变时的动画效果时,通常使用Selector进行设置。示例代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<!-- animate the translationZ property of a view when pressed -->
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true">
<set>
<objectAnimator android:propertyName="translationZ"
android:duration="@android:integer/config_shortAnimTime"
android:valueTo="2dp"
android:valueType="floatType"/>
<!-- you could have other objectAnimator elements
here for "x" and "y", or other properties -->
</set>
</item>
<item android:state_enabled="true"
android:state_pressed="false"
android:state_focused="true">
<set>
<objectAnimator android:propertyName="translationZ"
android:duration="100"
android:valueTo="0"
android:valueType="floatType"/>
</set>
</item>
</selector>

定义好对应的XML文件后,将其作为View的android:stateListAnimator属性,就可以使用对应的动画。

同样的,可以在代码中调用AnimatorInflater.loadStateListAnimator()方法加载XML文件,然后通过View.setStateListAnimator()方法将动画设置到对应的View上。

当时用Material主题时,Button默认带有translationZ的动画,如果不需要这个动画,可以将android:stateListAnimator属性设置为@null

AnimatedStateListDrawable

AnimatedStateListDrawable可以为View的状态切换设置可绘制动画,Android5.0中很多系统组件就使用了这样的的动画效果,具体可以通过animated-selector进行定义,示例代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<!-- res/drawable/myanimstatedrawable.xml -->
<animated-selector
xmlns:android="http://schemas.android.com/apk/res/android">

<!-- provide a different drawable for each state-->
<item android:id="@+id/pressed" android:drawable="@drawable/drawableP"
android:state_pressed="true"/>
<item android:id="@+id/focused" android:drawable="@drawable/drawableF"
android:state_focused="true"/>
<item android:id="@id/default"
android:drawable="@drawable/drawableD"/>

<!-- specify a transition -->
<transition android:fromId="@+id/default" android:toId="@+id/pressed">
<animation-list>
<item android:duration="15" android:drawable="@drawable/dt1"/>
<item android:duration="15" android:drawable="@drawable/dt2"/>
...
</animation-list>
</transition>
...
</animated-selector>
坚持原创技术分享,您的支持将鼓励我继续创作!