看完这篇再不会 View 的动画框架,我跪搓衣板
引言
众所周知,一款没有动画的 app,就像没有灵魂的肉体,给用户的体验性很差。现在的 android 在动画效果方面早已空前的发展,1.View 动画框架 2.属性动画框架 3.Drawable 动画。相比后后两者,View 动画框架在 Android 的最开始就已经出现,即有着非常容易学习的有点,却也有着用法太死的毛病,但对于初学者而言,猪狗实现各种可选的效果了。
组成
对于 View 的动画框架而言,最常见的有:
- AlphaAnimation(透明度动画)、
- RotateAnimation(旋转动画)、
- ScaleAnimation(缩放动画)、
- TranslateAnimation(平移动画)四种类型。
除此之外还提供了动画集合类(AnimationSet),用于将各种基本动画组合起来进行显示。
使用
对于现在市面上的书籍 📚,基本都是在活动代码中,一步一步设置透明度,运行时间。来对控件添加动画框架。所以我这里还是只讲 Java 代码添加那就太无聊了。所以这里我向大家介绍的使用方法,除了基本的以代码形式添加之外,更有 xml 文件的格式书写,并在活动中直接引用🚰的骚操作。
如果大家对其他动画方式,比如 Drawable 动画啊,属性动画啊感兴趣,欢迎查看我以后的博文。
既然是要在 xml 中配置,那我献给大家介绍下,xml 中各种属性的意义:在 /res 下建立 名为 “anim” 的 Directory,将以后的 xml 配置文件都放在该目录下。
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:shareInterpolator="true">
<!--透明度更变动画-->
<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>
下面,我就开始带领大家,以 ImageView TextView 为例,展示下使用方法,开始发干货咯:
在开始前
重点:唠叨一下
这里给出布局文件以后都是这样的,就不再给出了
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical"
tools:context=".AlphaAnimationActivity">
<!--不建议用 Relativelayout 浪费内存 哈哈哈-->
<ImageView
android:id="@+id/image"
android:layout_width="300dp"
android:layout_height="200dp"
android:src="@drawable/girl"
android:scaleType="fitXY"
android:alpha="1.0"/>
<!--这里的 alpha 设置的是最大透明度-->
<TextView
android:id="@+id/text"
android:layout_width="250dp"
android:layout_height="250dp"
android:gravity="center"
android:text="@string/text"
android:background="@color/papayawhip"
android:alpha="0.75"/>
</LinearLayout>
** 在布局文件中,对控件设置 alpha 值,表示最大的透明度**
透明度动画 -> Alpha
在 xml 文件中设置 alpha 动画,主要分为三个属性
- fromAlpha 表示开始时的透明度
- toAlpha 表示结束时的透明度
- duration 表示变化经历过程所占时间
在 /res/anim 下建立 alpha_anim.xml 文件
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<alpha
android:fromAlpha="0.0"
android:toAlpha="1.0"
android:duration="1000"/>
</set>
然后直接在活动中实例化 Animate 对象,引用即可
Animation animation = AnimationUtils.loadAnimation(this, R.anim.alpha_anim);
animation.setFillAfter(false);// 变化之后是永久更改还是恢复原样
ImageView imageView = findViewById(R.id.image);
imageView.startAnimation(animation);
TextView textView = findViewById(R.id.text);
textView.startAnimation(animation);
注意这个 setFillAfter 是用于设定:控件变化之后是永久更改,还是运行完了就恢复原样
运行一下,看效果:
缩放动画 -> Scale
在属性文件(xml)中,scale 的标签主要有一下这几个
- duration 运行时间
- fromXScale 横轴方向开始变化时的大小
- toXScale 横轴方向变化结束时的大小
- fromYScale 纵轴方向开始变化时的大小
- toYScale 纵轴方向变化结束时的大小
- pivotX 按比例确定缩小/放大中心点的横坐标
- pivotY 按比例确定缩小/放大中心点的纵坐标
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<scale
android:duration="2000"
android:fromXScale="1.0"
android:toXScale="0.0"
android:fromYScale="1.0"
android:toYScale="0.0"
android:pivotX="50%"
android:pivotY="50%"/>
</set>
如果你愿意,可以在布局文件中设置,默认开始是的缩放比例:
见名知意:
- scaleX 横向默认缩放比
- scaleY 纵向默认缩放比
<ImageView
android:id="@+id/scale_image"
android:layout_width="300dp"
android:layout_height="200dp"
android:src="@drawable/girl"
android:scaleType="fitXY"
android:scaleY="0.75"
android:scaleX="1.15"/>
**能达到如下的效果 **
同样的在活动中引用该属性文件:
和前面无异,改个文件即可
。。。
Animation animation = AnimationUtils.loadAnimation(this, R.anim.scale_anim);
animation.setFillAfter(false);// 变化之后是永久更改还是恢复原样
ImageView imageView = findViewById(R.id.scale_image);
imageView.startAnimation(animation);
。。。
运行一下看看效果:
平移动画 -> Translate
平移动画相对其他简单的属性动画来说,更为简单,主要有五个属性:
- duration 运行时间
- fromXDelta 在 X 轴的开始位置
- toXDelta 在 X 轴的结束位置
- fromYDelta 在 Y 轴的开始位置
- toYDelta 在 Y 轴的结束位置
注意,这里有个点比较特殊:
在确定位置属性的时候,有三种类型的赋值方法:
- 整型值:如:android:fromXDelta="20" 表示自己与左边界的距离
- 百分比:如:android:fromXDelta="20%" 表示自己与左边界的距离 和 自己高度的百分比
- 百分比+p:如:android:fromXDelta="20%p" 表示自己与父控件(一般为 ViewGroup )左边界的距离
篇幅问题,这里我只介绍整型值的使用方法
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate
android:duration="2000"
android:fromXDelta="20"
android:toXDelta="100"
android:fromYDelta="20"
android:toYDelta="100"/>
</set>
同样的也可以在布局文件中加以引用,这顶初始值:
<ImageView
android:id="@+id/scale_image"
android:layout_width="300dp"
android:layout_height="200dp"
android:src="@drawable/girl"
android:scaleType="fitXY"
android:translationX="50sp"
android:translationY="20sp"/>
可以看到,设定了初始位移的 ImageView 相对与未设定的 TextView 发生了偏移
同样的,在活动中加以引用:
...
Animation animation = AnimationUtils.loadAnimation(this, R.anim.translate_anim);
animation.setFillAfter(false);// 变化之后是永久更改还是恢复原样
ImageView imageView = findViewById(R.id.scale_image);
imageView.startAnimation(animation);
...
运行一下看看效果:
旋转动画 -> Rotate
对于旋转动画而言,一切就显得有趣了起来,我码字的双手就显得疲惫了起来
首先还是设定属性,对于旋转动画,基本的属性有:
- duration 动画时间
- fromDegrees 动画开始角度
- toDegrees 动画结束偏转角度
- pivotX 旋转轴心点 X 位置
- pivotY 旋转轴心点 Y 位置
同样的 旋转动画的属性也有三种设置方法,但这主要是对于 pivot 而言,用于确定轴心点位置
- 整型值:如:android:pivotX="20" 表示自己与左边界的距离
- 百分比:如:android:pivotX="20%" 表示自己与左边界的距离 和 自己高度的百分比
- 百分比+p:如:android:pivotX="20%p" 表示自己与父控件(一般为 ViewGroup )左边界的距离
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<rotate
android:duration="2000"
android:fromDegrees="0"
android:toDegrees="+360"
android:pivotX="50%"
android:pivotY="50%"/>
</set>
老样子,添加布局
<ImageView
android:id="@+id/scale_image"
android:layout_width="300dp"
android:layout_height="200dp"
android:src="@drawable/girl"
android:scaleType="fitXY"/>
在活动中添加代码
...
Animation animation = AnimationUtils.loadAnimation(this, R.anim.rotate_anim);
animation.setFillAfter(false);// 变化之后是永久更改还是恢复原样
ImageView imageView = findViewById(R.id.scale_image);
imageView.startAnimation(animation);
...
同样的在运行一下
这时你可能会揪着我稀疏的秀发问我,这有趣在哪里??!
好的请看!
360度无脑大旋转,好了牛逼吹完了,不告述你咋调的,我先跑了
开个玩笑啦,其实很简单,在布局文件中,设置下倾斜角就行了
- rotationX 横向倾斜角
- rotationY 纵向倾斜角
<ImageView
android:id="@+id/scale_image"
android:layout_width="300dp"
android:layout_height="200dp"
android:src="@drawable/girl"
android:scaleType="fitXY"
android:rotationX="50"
android:rotationY="20"/>
时间插值器
好了,到此为止基本动画就结束了,现在咱来点猛的:对就是:时间插值器
什么是时间插值器?我刚学时其实也很懵逼,现在发觉还是给大家看例子方便
使用
首先教大家下使用方法,完了在以咋们透明度动画为例做纤细的介绍
首先看,这时我们原来透明度的代码:
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<alpha
android:fromAlpha="0.0"
android:toAlpha="1.0"
android:duration="1000"/>
</set>
运行效果,我们可以看到这是个比较均匀的变化过程
我们简单的添加一行:
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="@android:anim/accelerate_interpolator">
<alpha
android:fromAlpha="0.0"
android:toAlpha="1.0"
android:duration="5000"/>
</set>
再来 这次时间加到10s,方便看效果;
可以看到,变化的数独越来越快,这就是时间插值器:
常见的时间插值器有:
- android:interpolator="@android:anim/accelerate_interpolator" 设置动画为加速动画(动画播放中越来越快)
就是这例子,这里不在说了
- android:interpolator="@android:anim/decelerate_interpolator" 设置动画为减速动画(动画播放中越来越慢)
- android:interpolator="@android:anim/accelerate_decelerate_interpolator" 设置动画为先加速在减速(开始速度最快 逐渐减慢)
- android:interpolator="@android:anim/anticipate_interpolator" 先反向执行一段,然后再加速反向回来(相当于我们弹簧,先反向压缩一小段,然后在加速弹出)
- android:interpolator="@android:anim/anticipate_overshoot_interpolator" 同上先反向一段,然后加速反向回来,执行完毕自带回弹效果(更形象的弹簧效果)
- android:interpolator="@android:anim/bounce_interpolator" 执行完毕之后会回弹跳跃几段(相当于我们高空掉下一颗皮球,到地面是会跳动几下)
- android:interpolator="@android:anim/cycle_interpolator" 循环,动画循环一定次数,值的改变为一正弦函数:Math.sin(2* mCycles* Math.PI* input)
- android:interpolator="@android:anim/linear_interpolator" 线性均匀改变
- android:interpolator="@android:anim/overshoot_interpolator" 加速执行,结束之后回弹
补间动画 -> Tween animation
抠完了上面每个的细节,我们玩波大的,首先我们先定义一个动画集合:
首先们还是,定义一个属性文件,但这里我们集合了 缩放 透明度 两种效果:
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="@android:anim/bounce_interpolator" >
<scale
android:duration="500"
android:fromXScale="0.1"
android:fromYScale="0.1"
android:pivotX="50%"
android:pivotY="50%"
android:toXScale="1.0"
android:toYScale="1.0" />
<alpha
android:duration="500"
android:fromAlpha="0"
android:toAlpha="1.0" />
</set>
然后我们在代码中,对 RecyclerView 设置它,对于 RecyclerView Adapter 的写法这里略去了,设置的详细方法如下:
private List<String> list;
private void iniList(){
list = new ArrayList<>();
for (int i = 0 ; i < 30 ; i ++){
list.add(i + " -- tween 测试 --");
}
}
private void iniRecyclerView(){
recyclerView = findViewById(R.id.recycler);
GridLayoutManager manager = new GridLayoutManager(this,1);
recyclerView.setLayoutManager(manager);
LayoutAnimationController lac=new LayoutAnimationController(AnimationUtils
.loadAnimation(this, R.anim.in_anim));
lac.setDelay(0.5f);
lac.setOrder(LayoutAnimationController.ORDER_RANDOM);
recyclerView.setLayoutAnimation(lac);
TweenRecyclerAdapter adapter = new TweenRecyclerAdapter(list);
recyclerView.setAdapter(adapter);
}
让我们运行下看看酷炫的效果:
如果文中有误,欢迎在评论区指出
怎么样,我不用贵搓衣板了吧,哈哈哈,点个赞呗么么哒~
本文以同步发布到我的 CSDN 博客,欢迎大家来捧场:
点击跳转 https://blog.csdn.net/qq_43377749/article/details/91890323