版权声明:本文为博主原创文章,未经博主允许不得转载。
本文纯个人学习笔记,由于水平有限,难免有所出错,有发现的可以交流一下。
一·、概述
安卓在 5.0 之后添加了 MaterialDesign 动画,主要有以下几种:
Touch feedback(触摸反馈)
Reveal effect(揭露效果)
Activity transitions(Activity 转换效果)
Curved motion(曲线运动)
View state changes (视图状态改变)
Animate Vector Drawables(可绘矢量动画)
二、触摸反馈
触摸反馈是在使用 MaterialDesign 主题的时候,点击按钮会有一个水波纹的扩散效果。
效果1
<Button
android:layout_width="match_parent"
android:minHeight="80dp"
android:gravity="center"
android:layout_height="wrap_content"
android:text="动画!" />
效果:
在这里什么都没有进行设置,只是 Activity 继承于 AppCompatActivity,则布局中的 Button 会被替换为 AppCompatButton。
效果2
<Button
android:layout_width="match_parent"
android:minHeight="80dp"
android:gravity="center"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:background="?android:attr/selectableItemBackground"
android:text="动画!" />
效果:
设置属性 android:background=”?android:attr/selectableItemBackground”。
效果3
<Button
android:layout_width="match_parent"
android:minHeight="80dp"
android:gravity="center"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:background="?android:attr/selectableItemBackgroundBorderless"
android:text="动画!" />
效果:
设置属性 android:background=”?android:attr/selectableItemBackgroundBorderless”,水波纹变成圆形的,超出了原本按钮的大小。
效果4
<Button
android:layout_width="match_parent"
android:minHeight="80dp"
android:gravity="center"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:background="@drawable/btn"
android:text="动画!" />
btn.xml:
<?xml version="1.0" encoding="utf-8"?>
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
android:color="@color/colorPrimaryDark">
</ripple>
效果:
通过设置 xml,可以修改背景颜色。
效果5
<Button
android:layout_width="match_parent"
android:minHeight="80dp"
android:gravity="center"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:background="@drawable/btn1"
android:text="动画!" />
btn1.xml:
<?xml version="1.0" encoding="utf-8"?>
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
android:color="@color/colorPrimaryDark">
<item android:drawable="@drawable/ic_launcher"/>
</ripple>
效果:
在 xml 中添加一个图片,这时候执行动画的效果就是图片大小。
效果6
<Button
android:layout_width="match_parent"
android:minHeight="80dp"
android:gravity="center"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:background="@drawable/btn2"
android:text="动画!" />
btn2.xml:
<?xml version="1.0" encoding="utf-8"?>
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
android:color="@color/colorPrimaryDark">
<item android:id="@android:id/mask" android:drawable="@drawable/ic_launcher"/>
</ripple>
效果:
在 xml 中添加 android:id=”@android:id/mask”,图片首先是不会出现的,点击之后才会出现。
三、揭露效果
<TextView
android:id="@+id/text_content"
android:layout_width="match_parent"
android:layout_height="100dp"
android:text="揭露效果"
android:gravity="center"
android:clickable="true"
/>
MainActivity :
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final TextView textView = ( TextView) findViewById(R.id.text_content);
textView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Animator animator = ViewAnimationUtils.createCircularReveal(textView,
textView.getWidth() / 2, textView.getHeight() / 2,
0, textView.getWidth());
animator.setDuration(3000);
animator.start();
}
});
}
}
效果:
代码非常简单,就是通过 createCircularReveal 方法来创建一个动画对象。
public static Animator createCircularReveal(View view,
int centerX, int centerY, float startRadius, float endRadius) {
return new RevealAnimator(view, centerX, centerY, startRadius, endRadius);
}
view 操作的视图
centerX 动画开始的中心点X
centerY 动画开始的中心点Y
startRadius 动画开始半径
startRadius 动画结束半径
四、Activity 转换效果
我们原先使用转场动画的时候是直接进行设置:
overridePendingTransition(android.R.anim.slide_in_left,android.R.anim.slide_out_right);
这种方式效果比较单一,在安卓 5.0 之后退出了一个 ActivityOptions,专门进行转场动画的制作,同时有个对应的兼容包 ActivityOptionsCompat,这个可以兼容到 2.3。
1.普通动画
普通动画有三种:
explode:从场景的中心移入或移出
slide:从场景的边缘移入或移出
fade:调整透明度产生渐变效果
style.xml:
<resources>
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item>
<!--是否覆盖执行,其实可以理解成是否同步执行还是顺序执行-->
<item name="android:windowAllowEnterTransitionOverlap">true</item>
<item name="android:windowAllowReturnTransitionOverlap">true</item>
<!-- 指定进入和退出transitions -->
<item name="android:windowEnterTransition">@android:transition/explode</item>
<item name="android:windowExitTransition">@android:transition/explode</item>
</style>
</resources>
Activity 的跳转使用 ActivityOptionsCompat 方式进行。
ActivityOptionsCompat comapt= ActivityOptionsCompat.makeSceneTransitionAnimation(this);
ActivityCompat.startActivity(this,new Intent(this,SecondActivity.class),comapt.toBundle());
效果:
修改进入退出样式为 slide。
style.xml:
<!-- 指定进入和退出transitions -->
<item name="android:windowEnterTransition">@android:transition/slide_bottom</item>
<item name="android:windowExitTransition">@android:transition/slide_bottom</item>
效果:
修改进入退出样式为 fade。
style.xml:
<!-- 指定进入和退出transitions -->
<item name="android:windowEnterTransition">@android:transition/fade</item>
<item name="android:windowExitTransition">@android:transition/fade</item>
效果:
这是普通的进入和突出动画,也可以在代码中进行设置。
Explode explode = (Explode)TransitionInflater.from(this).inflateTransition(R.transition.explode);
getWindow().setEnterTransition(explode);
Slide slide = new Slide(Gravity.BOTTOM);
slide.setDuration(1000L);
getWindow().setEnterTransition(slide);
Fade fade = new Fade();
fade.setDuration(1000L);
getWindow().setEnterTransition(fade);
2.共享元素
1.单个共享元素
MainActivity:
public class MainActivity extends AppCompatActivity {
View imageView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//设置标志位,允许转场动画
getWindow().requestFeature(Window.FEATURE_CONTENT_TRANSITIONS);
setContentView(R.layout.activity_main);
imageView = (ImageView) findViewById(R.id.img);
}
public void click(View view) {
ActivityOptionsCompat comapt= ActivityOptionsCompat.
makeSceneTransitionAnimation(this, imageView, getString(R.string.app_name));
ActivityOptionsCompat.makeSceneTransitionAnimation(this, img1, img2);
//跳转
ActivityCompat.startActivity(this,new Intent(this,SecondActivity.class),comapt.toBundle());
}
}
使用 ActivityOptionsCompat 进行转场动画的启动。要使用转场动画,需要在 Activity 中进行设置标志位,或者在 style.xml 中进行设置。
getWindow().requestFeature(Window.FEATURE_CONTENT_TRANSITIONS);
<item name="android:windowContentTransitions">true</item>
activity_main.xml:
<?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:layout_height="match_parent">
<Button
android:layout_width="match_parent"
android:layout_height="50dp"
android:onClick="click"
android:text="跳转"
/>
<ImageView
android:id="@+id/img"
android:layout_width="50dp"
android:layout_height="50dp"
android:src="@drawable/a"
android:transitionName="@string/app_name"
/>
</LinearLayout>
通过 android:transitionName 设置共享元素,从而实现转场动画。
SecondActivity :
public class SecondActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_second);
}
}
activity_second.xml:
<?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:layout_height="match_parent">
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="@drawable/a"
android:scaleType="centerCrop"
android:layout_weight="1"
android:transitionName="@string/app_name"
/>
</LinearLayout>
在第二个布局中的 ImageView 设置与第一个布局文件中相同的 android:transitionName,表示同一个转场元素。
效果:
2.多个共享元素
MainActivity 的 click:
public void click(View view) {
Pair<View, String> img1 = Pair.create(imageView, getString(R.string.app_name));
Pair<View, String> img2 = Pair.create(imageView2, getString(R.string.app));
ActivityOptionsCompat comapt= ActivityOptionsCompat.makeSceneTransitionAnimation(this, img1, img2);
//跳转
ActivityCompat.startActivity(this,new Intent(this,SecondActivity.class),comapt.toBundle());
}
效果:
3.自定义共享元素转换
changeBounds - 改变目标视图的布局边界
changeClipBounds - 裁剪目标视图边界
changeTransform - 改变目标视图的缩放比例和旋转角度
changeImageTransform - 改变目标图片的大小和缩放比例
style.xml:
<resources>
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item>
<!--是否覆盖执行,其实可以理解成是否同步执行还是顺序执行-->
<item name="android:windowAllowEnterTransitionOverlap">true</item>
<item name="android:windowAllowReturnTransitionOverlap">true</item>
<!-- 指定进入和退出transitions -->
<item name="android:windowEnterTransition">@android:transition/slide_bottom</item>
<item name="android:windowExitTransition">@android:transition/slide_bottom</item>
<!-- 指定shared element transitions -->
<item name="android:windowSharedElementEnterTransition">@transition/enter</item>
<item name="android:windowSharedElementExitTransition">@transition/enter</item>
</style>
</resources>
enter.xml:
<?xml version="1.0" encoding="utf-8"?>
<transitionSet xmlns:android="http://schemas.android.com/apk/res/android">
<changeBounds
android:duration="1000"
android:startDelay="0"
/>
</transitionSet>
整个 Activity 还是从底部进入,但是共享元素有自己的动画。