本章是讲解Android的动画机制,主要区别了视图动画和属性动画的区别,以及例举了视图的动画的使用和属性动画的使用,这篇博客还是记录学习过程中敲的代码,源码放在我的GitHub上
第九章源码:第九章源码
7.1 Android View动画框架
【注】视图动画只是实现了普通动画的效果,并不具有交互性,但使用方便,效率高
视图动画的使用:mView.startAnimation(ra);
- 布局:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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"
tools:context=".MainActivity">
<Button
android:id="@+id/buttonALPHA"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="ALPHA"
app:layout_constraintBottom_toTopOf="@+id/buttonROTATE"
app:layout_constraintEnd_toEndOf="@+id/buttonROTATE"
app:layout_constraintStart_toStartOf="@+id/buttonROTATE"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:id="@+id/buttonROTATE"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="ROTATE"
app:layout_constraintBottom_toTopOf="@+id/buttonROTATE_SELF"
app:layout_constraintEnd_toEndOf="@+id/buttonROTATE_SELF"
app:layout_constraintStart_toStartOf="@+id/buttonROTATE_SELF"
app:layout_constraintTop_toBottomOf="@+id/buttonALPHA" />
<Button
android:id="@+id/buttonROTATE_SELF"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="ROTATE_SELF"
app:layout_constraintBottom_toTopOf="@+id/buttonTRANSLATE"
app:layout_constraintEnd_toEndOf="@+id/buttonTRANSLATE"
app:layout_constraintStart_toStartOf="@+id/buttonTRANSLATE"
app:layout_constraintTop_toBottomOf="@+id/buttonROTATE" />
<Button
android:id="@+id/buttonTRANSLATE"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="TRANSLATE"
app:layout_constraintBottom_toTopOf="@+id/buttonSCALE"
app:layout_constraintEnd_toEndOf="@+id/buttonSCALE"
app:layout_constraintStart_toStartOf="@+id/buttonSCALE"
app:layout_constraintTop_toBottomOf="@+id/buttonROTATE_SELF" />
<Button
android:id="@+id/buttonSCALE"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="SCALE"
app:layout_constraintBottom_toTopOf="@+id/buttonSCALE_SELF"
app:layout_constraintEnd_toEndOf="@+id/buttonSCALE_SELF"
app:layout_constraintStart_toStartOf="@+id/buttonSCALE_SELF"
app:layout_constraintTop_toBottomOf="@+id/buttonTRANSLATE" />
<Button
android:id="@+id/buttonSCALE_SELF"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="SCALE_SELF"
app:layout_constraintBottom_toTopOf="@+id/buttonANIM_SELF"
app:layout_constraintEnd_toEndOf="@+id/buttonANIM_SELF"
app:layout_constraintStart_toStartOf="@+id/buttonANIM_SELF"
app:layout_constraintTop_toBottomOf="@+id/buttonSCALE" />
<Button
android:id="@+id/buttonANIM_SELF"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="ANIM_SELF"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/buttonSCALE_SELF" />
</androidx.constraintlayout.widget.ConstraintLayout>
-
代码:
视图动画
7.2 属性动画分析
ObjectAnimator、PropertyValuesHolder、ValueAnimator、AnimatorSet、在XML中使用、属性动画(X轴上放大为原来的两倍)、View的animate方法
- 布局:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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">
<Button
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.114"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.136" />
</androidx.constraintlayout.widget.ConstraintLayout>
-
代码:
Android属性动画分析
7.3 布局动画:
布局动画可以在ViewGroup处设置android:animateLayoutChanges="true"
,但我并没有看到书上描述的“子View呈现逐渐显示的过渡效果”,也可以根据代码实现自定义的动画
- 布局
<?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:id="@+id/ll"
android:background="@drawable/pear"
android:orientation="vertical">
<Button
android:id="@+id/layoutButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="136dp"
android:layout_marginLeft="136dp"
android:layout_marginTop="56dp"
android:text="Button" />
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/grape"/>
</LinearLayout>
-
代码:
布局动画
7.5 自定义动画
这里实现了两个动画:电视关闭动画和3D效果动画
【注】自定义动画继承的是Animation
而不是Animator
,
- 布局:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:id="@+id/myAnimationLayout"
android:layout_height="match_parent">
<Button
android:id="@+id/myAnimationBtn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button"/>
<ImageView
android:id="@+id/myAnimationImg"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/grape"/>
</LinearLayout>
-
代码:
MyAnimation---电视关闭效果
MyAnimation---3D效果动画
自定义动画的使用
7.6 SVG矢量动画机制
1. VectorDrawable、AnimatedVectorDrawable、objectAnimator的简单使用:
-
drawable
下建立一个vector.xml
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:height="200dp"
android:width="200dp"
android:viewportHeight="100"
android:viewportWidth="100">
<group
android:name="test"
android:rotation="0">
<path
android:strokeColor="@android:color/holo_blue_light"
android:strokeWidth="2"
android:pathData="
M 25 50
a 25,25 0 1,0 50,0"/>
</group>
</vector>
- 在
animator
目录下(自己创建的目录)创建一个anim_path1.xml
,当作动画
<?xml version="1.0" encoding="utf-8"?>
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="4000"
android:propertyName="rotation"
android:valueFrom="0"
android:valueTo="360">
</objectAnimator>
- 使用在
deawable
目录下建立的AnimatedVectorDrawable
,把VectorDrawable
和objectAnimated
连接起来,次文件为my_animated_vector.xml
<?xml version="1.0" encoding="utf-8"?>
<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
android:drawable="@drawable/vector">
<target
android:animation="@animator/anim_path1"
android:name="test"/>
</animated-vector>
- 使用:在View、ImageView等等View中使用
android:src="@drawable/my_animated_vector"
这个属性,然后在代码中调用:
//AnimatedVectorDrawable
//绑定添加了src属性的view
mImageView = findViewById(R.id.myAnimatedVectorImg);
//直接使用的方法:
((Animatable)mImageView.getDrawable()).start();
2. 线性动画:
-
VectorDrawable
——trick.xml
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:height="200dp"
android:width="200dp"
android:viewportHeight="100"
android:viewportWidth="100">
<group>
<path
android:name="path1"
android:strokeColor="@android:color/holo_green_dark"
android:strokeWidth="5"
android:strokeLineCap="round"
android:pathData="
M 20,80
L 50,80 80,80"/>
<path
android:name="path2"
android:strokeColor="@android:color/holo_green_dark"
android:strokeWidth="5"
android:strokeLineCap="round"
android:pathData="
M 20,20
L 50,20 80,20"/>
</group>
</vector>
-
objectAnimator
——linear_anim_path1
(上面的线)、linear_anim_path2
(下面的线)
linear_anim_path1
<?xml version="1.0" encoding="utf-8"?>
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="500"
android:propertyName="pathData"
android:valueFrom="
M 20,20
L 50,20 80,20"
android:valueTo="
M 20,20
L 50,50 80,20"
android:valueType="pathType"
android:interpolator="@android:anim/bounce_interpolator">
</objectAnimator>
linear_anim_path2
<?xml version="1.0" encoding="utf-8"?>
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="500"
android:propertyName="pathData"
android:valueFrom="
M 20,80
L 50,80 80,80"
android:valueTo="
M 20,80
L 50,50 80,80"
android:valueType="pathType"
android:interpolator="@android:anim/bounce_interpolator">
</objectAnimator>
-
AnimatedVectorDrawable
——linear_animated_vector.xml
<?xml version="1.0" encoding="utf-8"?>
<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
android:drawable="@drawable/trick">
<target
android:animation="@animator/linear_anim_path1"
android:name="path1"/>
<target
android:animation="@animator/linear_anim_path2"
android:name="path2"/>
</animated-vector>
- 使用:
布局:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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"
tools:context=".LinearAnimatorActivity">
<ImageView
android:id="@+id/linearAnimatorImg"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.393"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.182"
app:srcCompat="@drawable/linear_animated_vector" />
</androidx.constraintlayout.widget.ConstraintLayout>
代码

3. 模拟三球仪:
-
VectorDrawable
——three_ball.xml
-
objectAnimator
——sun_path.xml
、earth_path.xml
-
AnimatedVectorDrawable
——three_ball_animated_vector.xml
- 布局:
activity_three_ball.xml
- 代码:
ThreeBallActivity
4. 轨迹动画:
-
VectorDrawable
——searchbar.xml
-
objectAnimator
——anim_searchbar.xml
-
AnimatedVectorDrawable
——searchbar_animated_vector.xml
- 布局:
activity_search_bar.xml
- 代码:
SearchBarActivity
7.7Android动画特效
1. 灵动菜单:
- 布局:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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"
tools:context=".TouchWizActivity">
<ImageView
android:id="@+id/imageView_a"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.498"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.427"
app:srcCompat="@drawable/ic_add_circle_black_24dp" />
<ImageView
android:id="@+id/imageView_t"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="38dp"
app:layout_constraintBottom_toTopOf="@+id/imageView_a"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.498"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="1.0"
app:srcCompat="@drawable/ic_place_black_24dp" />
<ImageView
android:id="@+id/imageView_l"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="38dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/imageView_a"
app:layout_constraintHorizontal_bias="1.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.427"
app:srcCompat="@drawable/ic_wb_sunny_black_24dp" />
<ImageView
android:id="@+id/imageView_r"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="38dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toEndOf="@+id/imageView_a"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.427"
app:srcCompat="@drawable/ic_music_note_black_24dp" />
<ImageView
android:id="@+id/imageView_b"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="38dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.498"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/imageView_a"
app:layout_constraintVertical_bias="0.0"
app:srcCompat="@drawable/ic_camera_alt_black_24dp" />
</androidx.constraintlayout.widget.ConstraintLayout>
-
代码:
灵动菜单
2. 计时器动画:
- 布局:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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"
tools:context=".TimerActivity">
<TextView
android:id="@+id/timerTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Click Me"
android:textSize="48sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
-
代码:
计时器动画
3.下拉展开动画
- 布局:
<?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:orientation="vertical"
tools:context=".DropActivity">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:onClick="llClick"
android:background="@android:color/holo_blue_light"
android:orientation="horizontal">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:src="@drawable/ic_place_black_24dp"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="5dp"
android:gravity="left"
android:text="Click Me"
android:textSize="30sp"/>
</LinearLayout>
<LinearLayout
android:id="@+id/hidden_view"
android:layout_width="match_parent"
android:layout_height="40dp"
android:background="@android:color/holo_orange_light"
android:gravity="center_vertical"
android:orientation="horizontal"
android:visibility="gone">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:src="@drawable/ic_place_black_24dp"/>
<TextView
android:id="@+id/tv_hidden"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:gravity="center"
android:textSize="20sp"
android:text="I am hidden"/>
</LinearLayout>
</LinearLayout>
-
代码:
下拉展开
网友评论