前言
前篇我们已经介绍了很多基础动画知识,ViewAnimation , PropertyAnimator , 以及插值器和组合动画等等等等,这篇文章我们将会介绍一些在UI设计中,常用的几个动画用例.
动画
LayoutTransition
LayoutTransition(布局过渡效果)是Material design的重要方面,是因为它帮助用户理解app的操作流程,在用户切换视图的时候把不同组件间有机的结合起来.
官方解释:
当在ViewGroup容器中视图层次发生改变时,layoutTransition能够自动的设置过度的动画,在视图容器中为了能够转换,我们通过创建一个ViewGroup对象调用setLayoutTransition(LayoutTransition)在ViewGroup设置这个过渡动画,我们也可以在视图添加和删除时通过setAnimator()来设置动画.
接下来让我们看一下layoutTransition的使用
LayoutTransition transition = new LayoutTransition();//创建LayoutTransition的对象。
transition.setDuration(3000);//设置添加过度动画显示的时间。
transition.setAnimator(LayoutTransition.APPEARING, AnimatorInflater.loadAnimator(this, R.animator.animator));//添加动画
mGridLayout.setLayoutTransition(transition);//将LayoutTransition添加到ViewGroup容器中。
其中setAnimator(LayoutTransition.APPEARING, AnimatorInflater.loadAnimator(this, R.animator.animator))代表ViewGroup在有元素添加是,该元素的动画效果.第一个参数就是代表当添加新元素时.除此之外还有其他可以选择其他参数:
- APPEARING:当一个View在ViewGroup中出现时,对次View设置的动画
- CHANGE_APPEARING:当一个View在ViewGroup中出现时,对此View对其他View位置造成影响,对其他View设置的动画.
- DISAPPEARING:当一个View在ViewGroup中消失时,对此view设置的动画
- CHANGE_DISAPPEARING:当一个View在ViewGroup中出消失时,对次View对其他View位置造成影响,对其他View设置的动画.
- CHANGE:不是由于View出现或消失造成对其他View位置造成影响,然后对其他View设置的动画.
LayoutAnimation
LayoutAnimation是API Level 1 就已经有了,LayoutAnimation是对于viewGroup控件的所有的child view的操作,也就是说它是用来控制ViewGroup中所有的child view来显示的动画,LayoutAnimation动画可以直接在xml中定义:
<layoutAnimation xmlns:android="http://schemas.android.com/apk/res/android"
android:delay="30%"
android:animationOrder="reverse"
android:animation="@anim/slide_right"/>
1. android:delay表示动画播放的延时,既可以是百分比,也可以是float小数。
2. android:animationOrder表示动画的播放顺序,有三个取值normal(顺序)、reverse(反序)、random(随机)。
3. android:animation指向了子控件所要播放的动画。
可以通过下面两种方式加载:
- 直接在ViewGroup的layout xml文件中设置:
android:layoutAnimation="@anim/customer_anim"
- 在代码中加载:
Animation animation=AnimationUtils.loadAnimation(this, R.anim.slide_right); //得到一个LayoutAnimationController对象;
LayoutAnimationController controller = new LayoutAnimationController(animation); //设置控件显示的顺序;
controller.setOrder(LayoutAnimationController.ORDER_REVERSE); //设置控件显示间隔时间;
controller.setDelay(0.3); //为ListView设置LayoutAnimationController属性;
listView.setLayoutAnimation(controller);
listView.startLayoutAnimation();
Activity Transtition
Activitry Transition 为应用中的切换页面时,提供了非常优雅的视觉切换效果.我们可以为进入,退出,转换,页面之间的元素共享指定特定的动画.
页面过渡Transition
Mater Design为应用中的切换页面时,提供了非常优雅的视觉切换效果.您可为进入,退出,页面之间的共享元素转换设置特定的动画.
1. Transition动画都包含那些?
Android5.0(API级别 21)支持进入与退出转换的有三个:
Explode | Slide | Fade |
---|---|---|
从中心移入或移出 | 从边缘移入或移出 | 调整透明度产生渐变 |
这三个类都继承于Transition,所有有一些属性都是共同的.
常用属性如下:
/ 设置动画的时间。类型:long
transition.setDuration();
// 设置修饰动画,定义动画的变化率,具体设置往下翻就看到了
transition.setInterpolator();
// 设置动画开始时间,延迟n毫秒播放。类型:long
transition.setStartDelay();
// 设置动画的运行路径
transition.setPathMotion();
// 改变动画 出现/消失 的模式。Visibility.MODE_IN:进入;Visibility.MODE_OUT:退出。
transition.setMode();
// 设置动画的监听事件
transition.addListener()
- 定义方式
在java代码中定义:
Explode transition = new Explode();
transition.setDuration(500);
transition.setInterpolator(new AccelerateInterpolator());
在Xml资源定义:
android:duration="@integer/anim_duration_long"
android:interpolator="@android:interpolator/bounce"
/>
关于Interpolator不熟悉的请浏览前篇.
- 设置Transition时机
到底该什么时候呢,设置什么样的过渡呢?
以下为动画的设置场景:
首页打开页面A:
页面A->enter首次进入
从A打开B:
页面A->Exit退出
页面B->Enter首次进入
从B返回A:
页面B->Return 返回
页面A->Reenter重新进入
可设置的方法如下:
android:windowContentTransitions 允许使用transitions
android:windowAllowEnterTransitionOverlap 是否覆盖执行,其实可以理解成前后两个页面是同步执行还是顺序执行
android:windowAllowReturnTransitionOverlap 与上面相同。即上一个设置了退出动画,这个设置了进入动画,两者是否同时执行。
android:windowContentTransitionManager 引用TransitionManager XML资源,定义不同窗口内容之间的所需转换。
android:windowEnterTransition 首次进入显示的动画
android:windowExitTransition 启动新 Activity ,此页面退出的动画
android:windowReenterTransition 重新进入的动画。即第二次进入,可以和首次进入不一样。
android:windowReturnTransition 调用 finishAfterTransition() 退出时,此页面退出的动画
android:windowSharedElementsUseOverlay 指示共享元素在转换期间是否应使用叠加层。
android:windowSharedElementEnterTransition 首次进入显示的动画
android:windowSharedElementExitTransition 启动新 Activity ,此页面退出的动画
android:windowSharedElementReenterTransition 重新进入的动画。即第二次进入,可以和首次进入不一样。
android:windowSharedElementReturnTransition 调用 finishAfterTransition() 退出时,此页面退出的动画
以上为在style中设置属性,也可以在在代码中设置为:
getWindow().setEnterTransition(visibility);
// 其余的都是类似
- 跳转页面
至此,用以上知识基本可以设置出绝大多数的过渡效果.然后,跳转页面跟普通的跳转也有点不一样.
跳转页面
protected void transitionTo(Intent i) {
ActivityOptionsCompat transitionActivityOptions = ActivityOptionsCompat.makeSceneTransitionAnimation(this);
startActivity(i, transitionActivityOptions.toBundle());
}
**
退出页面
private void closeActivity(){
// 如果定义了 return transition ,将使用 定义的动画过渡
Visibility returnTransition = buildReturnTransition();
getWindow().setReturnTransition(returnTransition);
// 如果没有 return transition 被定义,将使用 反进入 的动画
finishAfterTransition();
}
注意退出时一定要调用:finishAfterTransition();
通过以上设置,就能够完成一个基本的过渡效果了.
- Shared Elements Transition共享元素
共享元素和各种设置与普通的Transition差不多,我们来看看不同的地方
需要携带共享的View进行跳转
也就是在跳转的参数中,增加了要共享的View控件
代码如下:
protected void transitionTo(Intent i) {
ActivityOptions options = ActivityOptions.makeSceneTransitionAnimation(this,
Pair.create(view1, "agreedName1"),
Pair.create(view2, "agreedName2"));
startActivity(i, options.toBundle());
}
增加的参数的介绍:
Pair.create(
View view, // 本页面要共享的 View
String resId // 共享控件的transitionName属性
)
注意共享的控件必须有同样的transitionName属性
- 页面改变时,动画的效果设置
changeBounds - 改变目标视图的布局边界
changeClipBounds - 裁剪目标视图边界
changeTransform - 改变目标视图的缩放比例和旋转角度
changeImageTransform-改变目标图片的大小和缩放比例
设置代码:
Slide slide = new Slide();
slide.setDuration(500);
ChangeBounds changeBounds = new ChangeBounds();
changeBounds.setDuration(500);
getWindow().setEnterTransition(slide);
getWindow().setSharedElementEnterTransition(changeBounds);
-
TransitionManager控制动画
这个框架可以让一些复杂的动画特别简单实现
简单说明一下步骤:
- 定义需要切换layout xml页面;
- 调用Scence.getSceneForLayout()保存每个Layout;
- 调用了TransitionManager.go(scene1, new ChangeBounds())切换.
相当于定义了不同的xml布局,然后通过简单的调用,就完成了复杂的动画.
代码如下:
private void setupLayout() {
scene0 = Scene.getSceneForLayout(binding.sceneRoot, R.layout.activity_animations_scene0, this);
scene1 = Scene.getSceneForLayout(binding.sceneRoot, R.layout.activity_animations_scene1, this);
scene2 = Scene.getSceneForLayout(binding.sceneRoot, R.layout.activity_animations_scene2, this);
scene3 = Scene.getSceneForLayout(binding.sceneRoot, R.layout.activity_animations_scene3, this);
scene4 = Scene.getSceneForLayout(binding.sceneRoot, R.layout.activity_animations_scene4, this);
binding.sample3Button1.setOnClickListener(this);
binding.sample3Button2.setOnClickListener(this);
binding.sample3Button3.setOnClickListener(this);
binding.sample3Button4.setOnClickListener(this);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.sample3_button1:
TransitionManager.go(scene1, new ChangeBounds());
break;
case R.id.sample3_button2:
TransitionManager.go(scene2, TransitionInflater.from(this).inflateTransition(R.transition.slide_and_changebounds));
break;
case R.id.sample3_button3:
TransitionManager.go(scene3,TransitionInflater.from(this).inflateTransition(R.transition.slide_and_changebounds_sequential));
break;
case R.id.sample3_button4:
TransitionManager.go(scene3,TransitionInflater.from(this).inflateTransition(R.transition.slide_and_changebounds_sequential_with_interpolators));
break;
}
}
只需要定义布局,调用调转,
就实现了,点击四个 Button ,分别切换四个布局。
TransitionManager.go() 中可以设置各种动画。
Touch Feedback触摸反馈
在Android L5.0中加入了触摸反馈动画
其中最明显,最具代表性的就是波纹动画,比如点击按钮或者条目时,会从点击的位置产生类似于波纹的效果.
- 波纹效果(Ripple)
当你使用了Material主题后,波纹动画会自动应用在所在控件上,我们当然可以来设置其属性来调整到我们需要的效果.
可以通过如下代码设置波纹的背景:
- android:background="?android:attr/selectableItemBackground" 波纹有边界
android:background="android:attr/selectableItemBackgroundBorderless" 波纹超出边界
使用效果如下:
- B1是不设任何背景的按钮
- B2设置了?android:attr/selectableItemBackground
- B3设置了?android:attr/selectableItemBackgroundBorderless
[图片上传失败...(image-60cc54-1521107181030)]
)
设置颜色
我们也可以通过xml属性来调节动画颜色,从而可以适应不同的主题:
android:colorControlHighlight:设置波纹颜色
android:coloeAccent:设置checkbox等控件选中后的颜色
Cricular Reveal圆形揭示
ViewAnimationUtils.creatCircularReveal()当显示或隐藏一组UI时,CircularReveal可为用户提供视觉连续性.
![](https://img.haomeiwen.com/i1689895/d44ca7efa847edbc.gif)
参数说明:
Animator createCircularReveal (View view, // 将要变化的 View
int centerX, // 动画圆的中心的x坐标
int centerY, // 动画圆的中心的y坐标
float startRadius, // 动画圆的起始半径
float endRadius // 动画圆的结束半径
)
显示View:
private void animShow() {
View myView = findViewById(R.id.my_view);
// 从 View 的中心开始
int cx = (myView.getLeft() + myView.getRight()) / 2;
int cy = (myView.getTop() + myView.getBottom()) / 2;
int finalRadius = Math.max(myView.getWidth(), myView.getHeight());
//为此视图创建动画设计(起始半径为零)
Animator anim = ViewAnimationUtils.createCircularReveal(myView, cx, cy, 0, finalRadius);
// 使视图可见并启动动画
myView.setVisibility(View.VISIBLE);
anim.start();
}
隐藏View:
private void animHide() {
final View myView = findViewById(R.id.my_view);
int cx = (myView.getLeft() + myView.getRight()) / 2;
int cy = (myView.getTop() + myView.getBottom()) / 2;
int initialRadius = myView.getWidth();
// 半径 从 viewWidth -> 0
Animator anim = ViewAnimationUtils.createCircularReveal(myView, cx, cy, initialRadius, 0);
anim.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
myView.setVisibility(View.INVISIBLE);
}
});
anim.start();
}
View state changes View状态改变
View state changes设置很简单,就是利用selector标签定义一个xml文件,使得view在状态改变时做出动画.
- 定义一个xml文件资源selector
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true">
<set>
<objectAnimator android:duration="@android:integer/config_shortAnimTime"
android:propertyName="rotationX"
android:valueTo="30"
android:valueType="floatType"/>
</set>
</item>
<item android:state_pressed="false">
<set>
<objectAnimator android:duration="@android:integer/config_shortAnimTime"
android:propertyName="rotationX"
android:valueTo="0"
android:valueType="floatType"/>
</set>
</item>
</selector>
2. 使用方法
- 布局:android:stateListAnimator属性将其分配给视图
- 代码:使用AniamtionInflater.loadStateListAnimator()方法读取,并且通过View.setStateListAnimator()方法分配动画到你的视图上
注意:
在代码使用的时候要让试图具有onClick功能.
Animate Vector Drawables可动画的矢量图
概述:
Vector(矢量图)对比Bitmap(位图)
绘制效率:Vector依赖于CPU计算,适合图像简单的情况.Bitmap可借助与GPU加速,适合图像复杂的情况
适用情况:Vector适用于ICON,Button,ImageView的小图片,或者需要动画效果时,Bitmap由于在GPU中有缓存功能,所以Bitmap不能做频繁的重绘.
加载速度:SVG快于PNG,但PNG有硬件加速,平均下来加载速度的提升弥补了绘制的速度缺陷.
VectorDrawable,矢量图动画.使用需要添加兼容库,在app的build.gradle文件相关节点下添加:
![](https://img.haomeiwen.com/i7232917/d77f15ba47fd0438.png)
1. 静态的VectorDrawable
像在ImageView,ImageButton这样的控件中使用是非常简单的:
<!-- 注意:这里用的是srcCompat -->
app:srcCompat="@drawable/vector_image"
如果要在Button这种带点击效果的控件中使用,则需要通过selector来进行设置,并在对应的Activity中开启下面的设置:
static {
AppCompatDelegate
.setCompatVectorFromResourcesEnabled(true);
}
2.使用动态的VectorDrawable
这里需要结合属性动画来实现VectorDrawable效果:
1)创建VectorDrawable文件arrow.xml
[图片上传失败...(image-4eeed1-1521107181030)]
Android Studio的Preview窗口显示的效果如下:
[图片上传失败...(image-b2bbf5-1521107181030)]
2)为VectorDrwable创建属性动画
anim_left.xml
![](https://img.haomeiwen.com/i7232917/b7a811d8b9d5fee5.png)
)
anim_right.xml
![](https://img.haomeiwen.com/i7232917/597f5129ca4e90c1.png)
3)下来使用动画粘合剂animated-vector(arrow_anim.xml),让属性动画作用于VectorDrawable:
![](https://img.haomeiwen.com/i7232917/c922f8b93b576c83.png)
4)粘合到一起以后,我们就可以在Activity的Layout文件中引用了:
![](https://img.haomeiwen.com/i7232917/07ff36d0c0715ea8.png)
5)在Activity中添加点击事件anim:
![](https://img.haomeiwen.com/i7232917/a176889225b60631.png)
6)至此编写完毕
![](https://img.haomeiwen.com/i7232917/e516396f14dcbb85.png)
- SVG和Vector
SVG是一套语法规范,在前端中使用.Vector只实现了SVG语法的Path()标签(为了提高解析效率),在Android中使用.
Vector的语法通过字母和数字的组合来描述一个路径,不同字母表示不同含义,例如:
M = moveto(M X,Y):讲画笔移动到指定的坐标位置
L = lineto(L X,Y):画直线到指定坐标
Z = closepath():关闭路径
Vector还提供了一些封装好的方法:
H = horizontal lineto(H X):画水平线到指定的X坐标位置
V = vertical lineto(V Y):画垂直线到指定的Y坐标的位置
这里只是介绍了用法,详细例子请参考http://www.10tiao.com/html/169/201702/2650822147/1.html
文章参考:
http://www.10tiao.com/html/169/201702/2650822147/1.html
https://www.jianshu.com/p/37ecb68c5ca1
https://www.jianshu.com/p/a43daa1e3d6e
网友评论