Material Design
Material Design是Google总结的一套具有创新性和符合科学的视觉规范,其中包含动画、排版,控件、资源、样式等。
官方介绍https://material.google.com/#
Material Design Animation
针对动画的一套具有创新性和符合科学的视觉规范
实际使用:
自然的加减速、用户的输入反馈、生动的场景切换动画、连贯的图标渐变动画
提供的效果:
(1)、触摸反馈
(2)、揭露效果
(3)、曲线运动
(4)、视图状态改变
(5)、可绘制矢量动画】
(6)、Activity切换动画
一、触摸反馈
(1)有界限的波纹,仅在View内
android:background="?android:attr/selectableItemBackground"
(2)无界限的波纹,延伸在View内
android:background="?android:attr/selectableItemBackgroundBorderless"
(3)自定义类型
在Drawable中定义ripple标签的xml
<?xml version="1.0" encoding="utf-8"?>
<!-- A blue ripple drawn atop a drawable resource. -->
<ripple
xmlns:android="http://schemas.android.com/apk/res/android"
android:color="#ff0000ff">
<item android:drawable="@mipmap/bg_custom_feedback" />
</ripple>
(4)取消波纹
background设置null或者其他颜色
android:background="@null"
注:5.0以上默认有波纹,5.0以下没有波纹
二、揭露效果
private static void circularHideBox(final View view) {
// get the center for the clipping circle
Rect rect = new Rect();
view.getLocalVisibleRect(rect);
int cx = rect.left + rect.width() / 2;
int cy = rect.top + rect.height() / 2;
// get the initial radius for the clipping circle
int initialRadius = view.getWidth();
// create the animation (the final radius is zero)
Animator anim = ViewAnimationUtils.createCircularReveal(view, cx, cy, initialRadius, 0);
anim.setDuration(1000);
// make the view invisible when the animation is done
anim.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
view.setVisibility(View.INVISIBLE);
}
});
// start the animation
anim.start();
}
三、曲线运动
示例代码
private void initMaterialDesignAnimation() {
ImageView materialButton = (ImageView) findViewById(R.id.material_ball);
Path path = new Path();
//path.moveTo(0, 100);
path.lineTo(100, 600);
path.cubicTo(200, 200, 300, 200, 400, 600);
path.cubicTo(500, 400, 550, 400, 600, 600);
PathInterpolator pathInterpolator = new PathInterpolator(0.8f, 0f, 1f, 1f);
final ObjectAnimator animator = ObjectAnimator.ofFloat(materialButton, View.X, View.Y, path);
animator.setInterpolator(pathInterpolator);
animator.setDuration(1000);
materialButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
animator.start();
}
});
}
四、视图状态改变
xml文件
<View
android:id="@+id/animate_view_state_changes"
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_gravity="center_horizontal"
android:background="@android:color/holo_orange_light"
android:clickable="true"
android:stateListAnimator="@animator/anim_view_state_changes"
android:textColor="@android:color/holo_green_dark"/>
drawable文件
<?xml version="1.0" encoding="utf-8"?>
<selector
xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true">
<objectAnimator
android:duration="@android:integer/config_shortAnimTime"
android:propertyName="translationZ"
android:valueTo="4dp"
android:valueType="floatType"/>
</item>
<item
android:state_pressed="false">
<objectAnimator
android:duration="100"
android:propertyName="translationZ"
android:valueTo="0"
android:valueType="floatType"/>
</item>
</selector>
代码文件
View stateChangeView = findViewById(R.id.animate_view_state_changes);
StateListAnimator stateLAnim = AnimatorInflater.loadStateListAnimator(this,
R.animator.anim_view_state_changes);
stateChangeView.setStateListAnimator(stateLAnim);
五、可绘制的矢量动画
1、静态矢量图
在res/drawable下使用定义的矢量图
<?xml version="1.0" encoding="utf-8"?>
<vector
xmlns:android="http://schemas.android.com/apk/res/android"
android:width="200dp"
android:height="200dp"
android:viewportHeight="100"
android:viewportWidth="100">
<!-- viewportHeight ,viewportWidth为定义一个坐标系-->
<!--group为path的集合-->
<group
android:name="menu_icon"
android:pivotX="50"
android:pivotY="50"
android:rotation="0">
<!--大写字母为绝对坐标,小写字母为相对坐标,z意思是闭合,m为moveto l 为lineto -->
<path
android:name="menu_icon_path"
android:pathData="@string/path_icon_menu"
android:strokeColor="@android:color/holo_red_dark"
android:strokeLineCap="round"
android:strokeWidth="@integer/stroke_width"/>
</group>
</vector>
2、动态矢量图
(1)在res/animator使用标签,定义单个动画资源
<?xml version="1.0" encoding="utf-8"?>
<objectAnimator
xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="@android:anim/linear_interpolator"
android:propertyName="rotation"
android:duration="1000"
android:valueFrom="0"
android:valueTo="180"/>
(2)在res/drawable 使用标签,组合多个动画资源
<?xml version="1.0" encoding="utf-8"?>
<animated-vector
xmlns:android="http://schemas.android.com/apk/res/android"
android:drawable="@drawable/vector_icon">
<target
android:name="menu_icon_path"
android:animation="@animator/anim_menu_to_arrow"/>
<target
android:name="menu_icon"
android:animation="@animator/anim_rotate"/>
</animated-vector>
相关资料:
https://www.w3.org/TR/SVG11/paths.html
六、Activity的转场动画
(1)启动transition api
getWindow().requestFeature(Window.FEATURE_CONTENT_TRANSITIONS);
getWindow().requestFeature(Window.FEATURE_ACTIVITY_TRANSITIONS);
(2)分别在调用与被调用的Activity中设置exit和enter transition
Activity1
Slide slideExitTransition = new Slide(Gravity.RIGHT);
getWindow().setExitTransition(slideExitTransition);
Activity2
Slide slideEnterTransition = new Slide(Gravity.BOTTOM); getWindow().setEnterTransition(slideEnterTransition);
(3)Activity1调用Acitivity.startActivity(Intent intent,Bundle options)启动Activity
Intent i = new Intent(Transition1Activity.this, Transition2Activity.class);
ActivityOptions transitionActivityOptions =
ActivityOptions.makeSceneTransitionAnimation(Transition1Activity.this);
startActivity(i, transitionActivityOptions.toBundle());
(4)Acitivity2调用Activity.finishAfterTransition()触发返回动画
finishAfterTransition();
7、Activity Share Element Transition
(1)AcitivityOptions中指定共享View和名称
Intent i = new Intent(Transition1Activity.this, Transition2Activity.class);
ActivityOptions transitionActivityOptions =
ActivityOptions.makeSceneTransitionAnimation(
Transition1Activity.this,
Pair.create(mFabButton, "fab"),
Pair.create(mHeader, "holder1"));
startActivity(i, transitionActivityOptions.toBundle());
(2)布局文件中指定共享View的transitionName
Activity1布局文件
<View
android:id="@+id/activity_transition_header"
android:layout_width="match_parent"
android:layout_height="144dp"
android:background="?android:colorPrimary"
android:transitionName="holder1"/>
Activity2布局文件
<View
android:id="@+id/activity_transition_header"
android:layout_width="match_parent"
android:layout_height="100dp"
android:background="?android:colorPrimary"
android:transitionName="holder1"/>