Android:ValueAnimator的使用举例
由来
很多人对ValueAnimator不熟悉,其实ValueAnimator的功能是非常强大的。它按照设定的时间和规则,在Update方法中将value友from变化到to。说起来很简单~
动画原理
我们可以使用ValueAnimator,将其由一个值变化为另外一个值,然后根据值的变化,按照一定的规则,动态修改View的属性,比如View的位置、透明度、旋转角度、大小等,即可完成了动画的效果。Yeah,就是这么简单。
Show My Code
package net.mobctrl.moveviews;
import net.mobctrl.moveviews.valueanimator.R;
import android.animation.AnimatorSet;
import android.animation.ValueAnimator;
import android.animation.ValueAnimator.AnimatorUpdateListener;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnTouchListener;
import android.view.animation.DecelerateInterpolator;
import android.view.animation.LinearInterpolator;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;
/**
*
* @author Zheng Haibo
* @web http://www.mobctrl.net
*
*/
@SuppressLint({ "ClickableViewAccessibility", "NewApi" })
public class MainActivity extends Activity implements OnTouchListener {
private ImageView ivMove;
private RelativeLayout rlRoot;
private TextView tvTips;
private int topTitleHeight;
private Button animatorBtn1;
private Button animatorBtn2;
private Button animatorBtn3;
private Button animatorBtn4;
private int width;
private int height;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
ivMove = (ImageView) findViewById(R.id.iv_move);
rlRoot = (RelativeLayout) findViewById(R.id.rl_root);
tvTips = (TextView) findViewById(R.id.tv_tips);
animatorBtn1 = (Button) findViewById(R.id.btn_move_animator_1);
animatorBtn2 = (Button) findViewById(R.id.btn_move_animator_2);
animatorBtn3 = (Button) findViewById(R.id.btn_move_animator_3);
animatorBtn4 = (Button) findViewById(R.id.btn_move_animator_4);
animatorBtn1.setOnClickListener(animatorClickListener);
animatorBtn2.setOnClickListener(animatorClickListener);
animatorBtn3.setOnClickListener(animatorClickListener);
animatorBtn4.setOnClickListener(animatorClickListener);
rlRoot.setOnTouchListener(this);
tvTips.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
}
});
}
@Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
int[] locations = new int[2];
tvTips.getLocationInWindow(locations);
topTitleHeight = locations[1];
break;
case MotionEvent.ACTION_MOVE:
moveViewByLayout(ivMove, (int) event.getRawX(),
(int) event.getRawY());
break;
case MotionEvent.ACTION_UP:
break;
}
return true;
}
/**
* 修改view的位置
*
* @param view
* @param rawX
* @param rawY
*/
private void moveViewByLayout(View view, int rawX, int rawY) {
int left = rawX - ivMove.getWidth() / 2;
int top = rawY - topTitleHeight - ivMove.getHeight() / 2;
int width = left + view.getWidth();
int height = top + view.getHeight();
view.layout(left, top, width, height);
}
private OnClickListener animatorClickListener = new OnClickListener() {
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btn_move_animator_1:
moveLinePath();
break;
case R.id.btn_move_animator_2:
moveCirclePath();
break;
case R.id.btn_move_animator_3:
rotateAndAlpha();
break;
case R.id.btn_move_animator_4:
scaleAnimator();
break;
default:
break;
}
}
};
/**
* 按直线轨迹运动
*/
protected void moveLinePath() {
width = rlRoot.getWidth();
height = rlRoot.getHeight();
ValueAnimator xValue = ValueAnimator.ofInt(width / 10, width / 2);
xValue.setDuration(1000);
xValue.addUpdateListener(new AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
// 轨迹方程 y = 1.5*x
int x = (Integer) animation.getAnimatedValue();
int y = (int) (1.5f * x);
System.out.println("debug:(x,y) = " + x + "," + y);
moveViewByLayout(ivMove, x, y);
}
});
xValue.setInterpolator(new LinearInterpolator());
xValue.start();
}
/**
* 先放大后缩小
*/
protected void scaleAnimator() {
final float scale = 0.6f;
AnimatorSet scaleSet = new AnimatorSet();
ValueAnimator valueAnimatorSmall = ValueAnimator.ofFloat(1.0f, scale);
valueAnimatorSmall.setDuration(500);
ValueAnimator valueAnimatorLarge = ValueAnimator.ofFloat(scale, 1.0f);
valueAnimatorLarge.setDuration(500);
valueAnimatorSmall.addUpdateListener(new AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
float scale = (Float) animation.getAnimatedValue();
ivMove.setScaleX(scale);
ivMove.setScaleY(scale);
}
});
valueAnimatorLarge.addUpdateListener(new AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
float scale = (Float) animation.getAnimatedValue();
ivMove.setScaleX(scale);
ivMove.setScaleY(scale);
}
});
scaleSet.play(valueAnimatorLarge).after(valueAnimatorSmall);
scaleSet.start();
}
/**
* 旋转的同时进行透明度变化
*/
protected void rotateAndAlpha() {
ValueAnimator valueAnimator = ValueAnimator.ofInt(0, 360);
valueAnimator.setDuration(1000);
valueAnimator.addUpdateListener(new AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
int rotateValue = (Integer) animation.getAnimatedValue();
ivMove.setRotation(rotateValue);
float fractionValue = animation.getAnimatedFraction();
ivMove.setAlpha(fractionValue);
}
});
valueAnimator.setInterpolator(new DecelerateInterpolator());
valueAnimator.start();
}
/**
* 圆形运行
*/
protected void moveCirclePath() {
width = rlRoot.getWidth();
height = rlRoot.getHeight();
final int R = width / 4;
ValueAnimator tValue = ValueAnimator.ofFloat(0,
(float) (2.0f * Math.PI));
tValue.setDuration(1000);
tValue.addUpdateListener(new AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
// 圆的参数方程 x = R*sin(t) y = R*cos(t)
float t = (Float) animation.getAnimatedValue();
int x = (int) (R * Math.sin(t) + width / 2);
int y = (int) (R * Math.cos(t) + height / 2);
System.out.println("debug:(x,y) = " + x + "," + y);
moveViewByLayout(ivMove, x, y);
}
});
tValue.setInterpolator(new DecelerateInterpolator());
tValue.start();
}
}
- * main.xml *
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/rl_root"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<TextView
android:id="@+id/tv_tips"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:text="move your finger on the screen,next activity -> click this" />
<LinearLayout
android:id="@+id/ll_btn"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/tv_tips"
android:orientation="horizontal" >
<Button
android:id="@+id/btn_move_animator_1"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Anim1" />
<Button
android:id="@+id/btn_move_animator_2"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Anim2" />
<Button
android:id="@+id/btn_move_animator_3"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Anim3" />
<Button
android:id="@+id/btn_move_animator_4"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Anim4" />
</LinearLayout>
<ImageView
android:id="@+id/iv_move"
android:layout_width="70dp"
android:layout_height="70dp"
android:layout_centerInParent="true"
android:background="@drawable/ic_launcher"
android:contentDescription="@null" />
</RelativeLayout>
项目链接
- * GitHub *
https://github.com/nuptboyzhb/MoveViewValueAnimator
更多交流
Android开发联盟QQ群:272209595
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。