文章目录
- 第三十二章 属性动画
- 属性动画
- 创造动画集
- 属性转化
- 相关小记(未完)
- 挑战练习
第三十二章 属性动画
属性动画
final ObjectAnimator sunsetSkyAnimator = ObjectAnimator
.ofInt(mSkyView, "backgroundColor",
mBuleSkyColor, mSunsetSkyColor)
.setDuration(3000);
sunsetSkyAnimator.setEvaluator(new ArgbEvaluator());
- 实现不同的动画特效
heightAnimation.setInterpolator(new AccelerateInterpolator());
//这里是加速的动画特效
创造动画集
animatorSet1 = new AnimatorSet();
animatorSet1
.play(heightAnimation)
.with(sunsetSkyAnimator)
.with(pointRadius)
.before(nightSkyAnimator);
animatorSet1.start();
animatorSet1.pause();
- 动画集的事件监听
1.监听动画的起始
对AnimatorSet.addListener(new AnimatorListenerAdapter(){});
中的方法进行实现
- 监听动画的暂停
实现AnimatorSet.addPauseListener(new Animator.AnimatorPauseListener(){})
中的相关方法
属性转化
- 旋转视图
rotation, privoteX, privoteY
- 缩放视图
scaleX, scaleY
- 移动视图
translationX, translationY
- 以上每个属性都有各自的setter和getter方法.
相关小记(未完)
挑战练习
- 再次点击屏幕, 让太阳上升
- 利用setRepeatCount(Int)实现太阳的有规律的放大缩小
- 在下落过程中点击后无缝回升到原来的位置
- 由于各种细节太过于麻烦, 以上的功能都实现了, 但整体不够好 ( Orz )
无缝回升需要API版本大于26
package com.bignerdranch.andriod.sunset;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.animation.ArgbEvaluator;
import android.animation.ObjectAnimator;
import android.annotation.SuppressLint;
import android.content.res.Resources;
import android.os.Build;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.AccelerateInterpolator;
public class SunsetFragment extends Fragment {
private View mSceneview;
private View mSunView;
private View mSkyView;
private int mBuleSkyColor;
private int mSunsetSkyColor;
private int mNightSkyColor;
public static float width;
public static float height;
private int i = 0;
private AnimatorSet animatorSet1;
private AnimatorSet animatorSet2;
private float mSunViewTop;
private float mSkyViewBottom;
private float currentSunViewTop;
private int currentSunsetSky;
private int currentNightSky;
private long currentTime;
private static final String TAG = "SunsetFragment";
public static SunsetFragment newInstance(){
return new SunsetFragment();
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_sunset, container, false);
mSceneview = view;
mSunView = view.findViewById(R.id.sun);
mSkyView = view.findViewById(R.id.sky);
Resources resources = getResources();
mBuleSkyColor = resources.getColor(R.color.blue_sky);
mSunsetSkyColor = resources.getColor(R.color.sunset_sky);
mNightSkyColor = resources.getColor(R.color.night_sky);
view.post(new Runnable() {
@Override
public void run() {
width = mSkyView.getWidth();
height = mSkyView.getHeight();自动得知
mSunViewTop = mSunView.getY();
mSkyViewBottom = mSkyView.getBottom();
currentSunViewTop = mSunView.getTop();
Log.i(TAG, " 你当前位置是 " + currentSunViewTop);
Log.i(TAG, " 底部位置是 " + mSkyViewBottom);
}
});
mSceneview.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (currentSunViewTop == mSunViewTop && i == 0) {
startAnimation1(mSunViewTop);
}else if (currentSunViewTop == mSkyViewBottom && i == 1){
startAnimation2(mSkyViewBottom, mSunsetSkyColor,
mNightSkyColor, 3200);
}else {
if (i == 1){
animatorSet1.pause();
startAnimation2(currentSunViewTop, currentSunsetSky,
currentNightSky, currentTime);
}
}
}
});
return view;
}
private void startAnimation1(float sunViewTop){
ObjectAnimator heightAnimation = ObjectAnimator
.ofFloat(mSunView, "y", sunViewTop, mSkyViewBottom)
.setDuration(3200);
heightAnimation.setInterpolator(new AccelerateInterpolator());
@SuppressLint("ObjectAnimatorBinding")
ObjectAnimator pointRadius = ObjectAnimator
.ofInt(mSunView, "PointRadius",
100, 150, 100)
.setDuration(3200);
pointRadius.setRepeatCount(1);
final ObjectAnimator sunsetSkyAnimator = ObjectAnimator
.ofInt(mSkyView, "backgroundColor",
mBuleSkyColor, mSunsetSkyColor)
.setDuration(3000);
sunsetSkyAnimator.setEvaluator(new ArgbEvaluator());
final ObjectAnimator nightSkyAnimator = ObjectAnimator
.ofInt(mSkyView, "backgroundColor",
mSunsetSkyColor, mNightSkyColor)
.setDuration(1500);
nightSkyAnimator.setEvaluator(new ArgbEvaluator());
animatorSet1 = new AnimatorSet();
animatorSet1.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationStart(Animator animation) {
super.onAnimationStart(animation);
currentSunViewTop = mSunView.getY();
Log.i(TAG, " animatorSet1 初始位置是 " + currentSunViewTop);
}
@Override
public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
currentSunViewTop = mSunView.getY();
Log.i(TAG, " animatorSet1 结束位置是 " + currentSunViewTop);
}
});
animatorSet1.addPauseListener(new Animator.AnimatorPauseListener() {
@Override
public void onAnimationPause(Animator animation) {
currentSunViewTop = mSunView.getY();
currentSunsetSky = (int) sunsetSkyAnimator.
getAnimatedValue("backgroundColor");
currentNightSky = (int) nightSkyAnimator.
getAnimatedValue("backgroundColor");
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
currentTime = animatorSet1.getCurrentPlayTime();
}
Log.i(TAG, " animatorSet1 暂停位置是 " + currentSunViewTop);
Log.i(TAG, " animatorSet1 暂停位置的颜色是 " + currentSunsetSky);
Log.i(TAG, " animatorSet1 暂停位置的夜间颜色是 " + currentNightSky);
Log.i(TAG, " animatorSet1 暂停位置的时间是 " + currentTime);
}
@Override
public void onAnimationResume(Animator animation) {
}
});
animatorSet1
.play(heightAnimation)
.with(sunsetSkyAnimator)
.with(pointRadius)
.before(nightSkyAnimator);
animatorSet1.start();
i++;
}
private void startAnimation2(float currentSunViewTop,int currentSunsetSky,
int currentNightSky, long currentTime){
@SuppressLint("ObjectAnimatorBinding")
ObjectAnimator pointRadius = ObjectAnimator
.ofInt(mSunView, "PointRadius",
100, 100)
.setDuration(currentTime);
ObjectAnimator heightAnimation = ObjectAnimator
.ofFloat(mSunView, "y", currentSunViewTop, mSunViewTop)
.setDuration(currentTime);
heightAnimation.setInterpolator(new AccelerateInterpolator());
ObjectAnimator sunUpSkyAnimator = ObjectAnimator
.ofInt(mSkyView, "backgroundColor",
currentSunsetSky, mBuleSkyColor)
.setDuration(currentTime);
sunUpSkyAnimator.setEvaluator(new ArgbEvaluator());
animatorSet2 = new AnimatorSet();
animatorSet2.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationStart(Animator animation) {
super.onAnimationStart(animation);
SunsetFragment.this.currentSunViewTop = mSunView.getY();
Log.i(TAG, " animatorSet2 开始位置是 " +
SunsetFragment.this.currentSunViewTop);
}
@Override
public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
SunsetFragment.this.currentSunViewTop = mSunView.getY();
Log.i(TAG, " animatorSet2 结束位置是 " +
SunsetFragment.this.currentSunViewTop);
}
});
if (currentTime > 3200){
ObjectAnimator nightSkyAnimator = ObjectAnimator
.ofInt(mSkyView, "backgroundColor",
currentNightSky, mSunsetSkyColor)
.setDuration(currentTime - 3200);
nightSkyAnimator.setEvaluator(new ArgbEvaluator());
animatorSet2
.play(heightAnimation)
.with(sunUpSkyAnimator)
.with(pointRadius)
.after(nightSkyAnimator);
}else if (currentTime == 3200){
ObjectAnimator nightSkyAnimator = ObjectAnimator
.ofInt(mSkyView, "backgroundColor",
mNightSkyColor, mSunsetSkyColor)
.setDuration(1500);
nightSkyAnimator.setEvaluator(new ArgbEvaluator());
animatorSet2
.play(heightAnimation)
.with(sunUpSkyAnimator)
.after(nightSkyAnimator);
}else {
animatorSet2
.play(heightAnimation)
.with(pointRadius)
.with(sunUpSkyAnimator);
}
animatorSet2.start();
i--;
}
}
- 自定义的view视图
MyPointView.java
package com.bignerdranch.andriod.sunset;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.view.View;
public class MyPointView extends View {
private Paint paint;
private Point mPoint = new Point(100);
public MyPointView(Context context) {
this(context, null);
}
public MyPointView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
paint = new Paint();
paint.setAntiAlias(true);
paint.setColor(Color.YELLOW);
paint.setStyle(Paint.Style.FILL);
}
@Override
protected void onDraw(Canvas canvas) {
if (mPoint != null){
canvas.drawCircle(SunsetFragment.width/2,SunsetFragment.height/2,
mPoint.getRadius(), paint);
}
}
public void setPointRadius(int radius){
mPoint.setRadius(radius);
invalidate();
}
}
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<FrameLayout
android:id="@+id/sky"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="0.61"
android:background="@color/blue_sky">
<com.bignerdranch.andriod.sunset.MyPointView
android:id="@+id/sun"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"/>
FrameLayout>
<View
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="0.39"
android:background="@color/sea"/>
LinearLayout>
package com.bignerdranch.andriod.sunset;
public class Point {
private int mRadius;
public Point(int radius){
mRadius = radius;
}
public int getRadius() {
return mRadius;
}
public void setRadius(int radius) {
mRadius = radius;
}
}