触摸反馈
波纹效果(Ripple)
可以通过如下代码设置波纹的背景:
android:background="?android:attr/selectableItemBackground"波纹有边界
android:background="?android:attr/selectableItemBackgroundBorderless"波纹超出边界
效果如下:
Activity Transition
在Android 5.0 上 ,加入了对Activity的进入、退出的动画效果。
提供了三种Transition类型:
- 进入:一个进入的过渡(动画)决定activity中的所有的视图怎么进入屏幕。
- 退出:一个退出的过渡(动画)决定一个activity中的所有视图怎么退出屏幕。
- 共享元素:一个共享元素过渡(动画)决定两个activities之间的过渡,怎么共享(它们)的视图。
进入&退出
1、Enter(进入):进入一个Activity的效果
2、Exit(退出):退出一个Activity的效果
1. 设置Activity的动画
我们可以使用以下API进行设置:
Window.setEnterTransition():普通transition的进入效果
Window.setExitTransition():普通transition的退出效果
Window.setSharedElementEnterTransition():共享元素transition的进入效果
Window.setSharedElementExitTransition():共享元素transition的退出效果
可以为Activity设置下面三种进入的效果。
explode:从场景的中心移入或移出
slide:从场景的边缘移入或移出
fade:调整透明度产生渐变效果
设置这几种效果可以使用代码实现,也可以使用xml文件实现。(两种选一种)
@Override
protected void onCreate(Bundle savedInstanceState) {
...
Transition t;
//代码实现
t = buildEnterExplodeTransition();
//读取xml实现
t = TransitionInflater.from(this).inflateTransition(R.transition.explode);
//设置进入动画
getWindow().setEnterTransition(t);
...
}
private Transition buildEnterExplodeTransition() {
Explode enterTransition = new Explode();
enterTransition.setDuration(500);
enterTransition.setInterpolator(new LinearOutSlowInInterpolator());
return enterTransition;
}
explode.xml文件:
<?xml version="1.0" encoding="utf-8"?>
<transitionSet xmlns:android="http://schemas.android.com/apk/res/android">
<explode
android:duration="500"
android:interpolator="@android:interpolator/bounce" />
</transitionSet>
2. 要想看到启动Activity启动或者退出带有这种效果。那么启动的方式也要发生改变:
startActivity(intentExplodeCode, ActivityOptions.makeSceneTransitionAnimation(this).toBundle());
共享元素
共享元素的实现也是和设置Activity的进入或者退出的实现方式一样。
不一样的是启动Activity时,要注明共享元素的名字。
只共享一个元素时:
// ivShare: 需要共享的视图
// "iv_share": 在布局文件上设置上android:transitionName="iv_share",名字随意命名。
ActivityOptions activityOptions = ActivityOptions.makeSceneTransitionAnimation(
StartTranstionActivity.this,
ivShare, "iv_share");
startActivity(intentShare, activityOptions.toBundle());
共享多个元素时:使用Pair.create()来一一对应,然后传入makeSceneTransitionAnimation中。
ActivityOptions activityOptions = ActivityOptions.makeSceneTransitionAnimation(
StartTranstionActivity.this,
Pair.create((View) ivShare, "iv_share"),
Pair.create((View)btnShare,"btn_share"));
和上面相比,只是ActivityOptions.makeSceneTransitionAnimation调用了另一个重载的方法,这个方法的第二个以后的参数就是共享元素的View和transitionName。
设置Fragment的进入与退出动画。
实现起来也十分简单,也是可以使用代码的形式实现,或者使用xml的形式来实现。
下面列子由代码来实现。
Slide slideTransition = new Slide(Gravity.LEFT);
slideTransition.setDuration(500);
//设置进入与退出效果
OneFragment oneFragment = new OneFragment();
oneFragment.setReenterTransition(slideTransition);
oneFragment.setEnterTransition(slideTransition);
oneFragment.setExitTransition(slideTransition);
oneFragment.setSharedElementEnterTransition(new ChangeBounds());
getSupportFragmentManager().beginTransaction()
.replace(R.id.fl, oneFragment)
.commit();
共享元素在 Activity 与 Fragment 之间使用
在这Activity 与 Fragment 之间使用,用法和在 Activity 与 Activity 之间使用是一样的。保证一点就是 Fragment 上要有 启动时 所要的共享元素。其他和上面没什么不同。
共享元素在 Fragment 与 Fragment 之间使用
getFragmentManager().beginTransaction()
.replace(R.id.fl, twoFragment)
//增加共享元素
.addSharedElement(ivShare,"iv_share")
.commit();
这个addSharedElement(ivShare,"iv_share")就是添加了共享元素。其他都是一样的。
增加transition的监听。
使用就只是直接调用一个API就能实现了。
getWindow().getEnterTransition().addListener(new Transition.TransitionListener() {
@Override
public void onTransitionStart(Transition transition) {
System.out.println("开始进入");
}
@Override
public void onTransitionEnd(Transition transition) {
System.out.println("进入结束");
}
@Override
public void onTransitionCancel(Transition transition) {
}
@Override
public void onTransitionPause(Transition transition) {
}
@Override
public void onTransitionResume(Transition transition) {
}
});
根据自己的所需的业务逻辑,就在上面添加逻辑就可以,通常我们可以用来制作一下动画效果。
View Animation
TransitionManager使得我们实现动画效果起来更加简单。
TransitionManager.beginDelayedTransition(llRoot);
TransitionManager.beginDelayedTransition(llRoot);这个方法,参数只要放入ViewGroup就可以了。当ViewGroup里面的元素的属性发生改变,那么就是自动补全中间的动画效果。
//改变图片的大小
TransitionManager.beginDelayedTransition(llRoot);
//取控件textView当前的布局参数
LinearLayout.LayoutParams params =(LinearLayout.LayoutParams) ivChange.getLayoutParams();
System.out.println(params.width);
params.width = 200+ivChange.getWidth();
params.height = 160+ivChange.getHeight();
ivChange.setLayoutParams(params);
//或者改变图片的位置
TransitionManager.beginDelayedTransition(llRoot);
LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) ivChange.getLayoutParams();
if (positionChanged) {
lp.gravity = Gravity.CENTER;
} else {
lp.gravity = Gravity.LEFT;
}
positionChanged = !positionChanged ;
ivChange.setLayoutParams(lp);
中间并没有实现任何动画代码,运行效果如下:
我们也可以使用他的另一个重载方法: public static void beginDelayedTransition(final ViewGroup sceneRoot, Transition transition),为第二个参数加入transition。就可以变成自己的想要的效果了。
Scene
Scene可以把一个布局上控件全部同时改变并且加上动画效果。
使用方法:
- 创建Scene
使用 public static Scene getSceneForLayout(ViewGroup sceneRoot, int layoutId, Context context)这个方法。
- sceneRoot指定一个ViewGroup,
- layoutId给定一个布局ID
- context....
sceneRoot = (FrameLayout) findViewById(R.id.scene_root);
scene1 = Scene.getSceneForLayout(sceneRoot, R.layout.activity_animations_scene1, this);
scene2 = Scene.getSceneForLayout(sceneRoot, R.layout.activity_animations_scene2, this);
开始动画:
TransitionManager.go(scene2, new ChangeBounds());
第二个参数就是Transition,设置自己想要的变化效果,如:
TransitionManager.go(scene2, TransitionInflater.from(ScenesActivity.this).
inflateTransition(R.transition.slide_and_changebounds_sequential));
上面设置两个Scene,注意的一点是布局上ID要有一样,否则系统不知道如何补充中间的动画。其实就是根据两个不同的布局下相同控件的位置进行计算并补全控件移动的动画。
同时我们也可以设置Scene动画监听:
//增加监听
scene2.setEnterAction(new Runnable() {
@Override
public void run() {
System.out.println("scene1进入");
}
});
scene2.setExitAction(new Runnable() {
@Override
public void run() {
System.out.println("scene1退出");
}
});
Circular Reveal
Circular Reveal是Android L新增的一个动画效果。
使用ViewAnimationUtils.createCircularReveal()方法可以去创建一个RevealAnimator动画
API如下:
public static Animator createCircularReveal(View view,
int centerX, int centerY, float startRadius, float endRadius) {
return new RevealAnimator(view, centerX, centerY, startRadius, endRadius);
}
middot;view 操作的视图
middot;centerX 动画开始的中心点X
middot;centerY 动画开始的中心点Y
middot;startRadius 动画开始半径
middot;startRadius 动画结束半径
因此可以实现下面的动画效果:
@Override
public void onClick(View v) {
switch (v.getId()){
case R.id.iv_green:
revealGreen();
break;
}
}
private void revealGreen() {
animateRevealColor(rlChange, R.color.sample_green);
}
private void animateRevealColor(ViewGroup viewRoot, @ColorRes int color) {
int cx = (viewRoot.getLeft() + viewRoot.getRight()) / 2;
int cy = (viewRoot.getTop() + viewRoot.getBottom()) / 2;
animateRevealColorFromCoordinates(viewRoot, color, cx, cy);
}
private Animator animateRevealColorFromCoordinates(ViewGroup viewRoot, @ColorRes int color, int x, int y) {
float finalRadius = (float) Math.hypot(viewRoot.getWidth(), viewRoot.getHeight());
Animator anim = ViewAnimationUtils.createCircularReveal(viewRoot, x, y, 0, finalRadius);
viewRoot.setBackgroundColor(ContextCompat.getColor(this, color));
anim.setDuration(500);
anim.setInterpolator(new AccelerateDecelerateInterpolator());
anim.start();
return anim;
}
效果如下: