編輯:關於Android編程
而在Animator框架中使用最多的是AnimatorSet和ObjectAnimator配合,使用ObjectAnimator進行更精細化控制,只控制一個對象的一個屬性值,多個ObjectAnimator組合到AnimatorSet形成一個動畫。而且ObjectAnimator能夠自動驅動,可以調用setFrameDelay(longframeDelay)設置動畫幀之間的間隙時間,調整幀率,減少動畫過程中頻繁繪制界面,而在不影響動畫效果的前提下減少CPU資源消耗。因此,Anroid推出的強大的屬性動畫框架,基本可以實現所有的動畫效果。
ObjectAnimator .ofFloat(view, rotationX, 0.0F, 360.0F) .setDuration(1000) .start();
animator.addUpdateListener(new AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator arg0) {
}
});
ObjectAnimator anim = ObjectAnimator.ofFloat(view, xxx, 1.0F, 0.0F)
.setDuration(500);
anim.start();
anim.addUpdateListener(new AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
floatcVal = (Float) animation.getAnimatedValue();
view.setAlpha(cVal);
view.setScaleX(cVal);
view.setScaleY(cVal);
}
});
private static class WrapperView {
private View mTarget;
public WrapperView(View target) {
mTarget = target;
}
public int getWidth() {
return mTarget.getLayoutParams().width;
}
public void setWidth(int width) {
mTarget.getLayoutParams().width = width;
mTarget.requestLayout();
}
}
ViewWrapper wrapper = new ViewWrapper(mButton); ObjectAnimator.ofInt(wrapper, width, 500).setDuration(5000).start();
public void propertyValuesHolder(View view) {
PropertyValuesHolder pvhX = PropertyValuesHolder.ofFloat(alpha, 1f,
0f, 1f);
PropertyValuesHolder pvhY = PropertyValuesHolder.ofFloat(scaleX, 1f,
0, 1f);
PropertyValuesHolder pvhZ = PropertyValuesHolder.ofFloat(scaleY, 1f,
0, 1f);
ObjectAnimator.ofPropertyValuesHolder(view, pvhX, pvhY, pvhZ)
.setDuration(1000).start();
}
ValueAnimator animator = ValueAnimator.ofFloat(0, 100);
animator.setTarget(view);
animator.setDuration(1000).start();
animator.addUpdateListener(new AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
Float value = (Float) animation.getAnimatedValue();
imageView.setTranslationY(value);
}
});
public Float evaluate(float fraction, Number startValue, Number endValue) {
float startFloat = startValue.floatValue();
return startFloat + fraction * (endValue.floatValue() - startFloat);
}
package com.example.animtest;
import android.animation.TypeEvaluator;
import android.animation.ValueAnimator;
import android.animation.ValueAnimator.AnimatorUpdateListener;
import android.app.Activity;
import android.graphics.PointF;
import android.os.Bundle;
import android.util.DisplayMetrics;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.view.animation.BounceInterpolator;
import android.view.animation.LinearInterpolator;
import android.widget.ImageView;
public class AnimateFreeFall extends Activity {
private int screenHeight;
private int screenWidth;
private ImageView imageView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.animate_free_fall);
DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
screenHeight = metrics.heightPixels;
screenWidth = metrics.widthPixels;
imageView = (ImageView) findViewById(R.id.im);
}
public void clean(View view) {
imageView.setTranslationX(0);
imageView.setTranslationY(0);
}
public void freefall(View view) {
final ValueAnimator animator = ValueAnimator.ofFloat(0, screenHeight
- imageView.getHeight());
animator.setTarget(view);
animator.setInterpolator(new BounceInterpolator());
animator.setDuration(1000).start();
animator.addUpdateListener(new AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
Float value = (Float) animation.getAnimatedValue();
imageView.setTranslationY(value);
}
});
}
public void parabola(View view) {
ValueAnimator animator = ValueAnimator.ofObject(
new TypeEvaluator() {
@Override
public PointF evaluate(float fraction, PointF arg1,
PointF arg2) {
PointF p = new PointF();
p.x = fraction * screenWidth;
p.y = fraction * fraction * 0.5f * screenHeight * 4f
* 0.5f;
return p;
}
}, new PointF(0, 0));
animator.setDuration(800);
animator.setInterpolator(new LinearInterpolator());
animator.start();
animator.addUpdateListener(new AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animator) {
PointF p = (PointF) animator.getAnimatedValue();
imageView.setTranslationX(p.x);
imageView.setTranslationY(p.y);
}
});
}
}
效果如下圖:

自定義TypeEvaluator傳入的泛型可以根據自己的需求,自己設計個Bean。
ObjectAnimator anim = ObjectAnimator.ofFloat(view, alpha, 0.5f);
anim.addListener(new AnimatorListener() {
@Override
public void onAnimationStart(Animator animation) {
}
@Override
public void onAnimationRepeat(Animator animation) {
}
@Override
public void onAnimationEnd(Animator animation) {
}
@Override
public void onAnimationCancel(Animator animation) {
}
});
anim.start();
anim.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
}
});
package com.example.animtest;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ObjectAnimator;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.ImageView;
public class AnimateMoveInSecond extends Activity {
private ImageView imageView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.animate_move_in_second);
imageView = (ImageView) findViewById(R.id.imageView1);
}
public void doit(View view) {
ObjectAnimator animator = ObjectAnimator.ofFloat(imageView, alpha,
1.0f, 0f);
animator.setDuration(1000);
animator.start();
animator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
ObjectAnimator animator = ObjectAnimator.ofFloat(imageView,
alpha, 0f, 1.0f);
animator.setDuration(1000);
animator.start();
imageView.setTranslationY(400);
}
});
}
}
效果如下圖:

ObjectAnimator animator1 = ObjectAnimator.ofFloat(imageView, scaleX, 1f, 2f); ObjectAnimator animator2 = ObjectAnimator.ofFloat(imageView, scaleY, 1f, 2f); ObjectAnimator animator3 = ObjectAnimator.ofFloat(imageView, translationY, 0f, 500f); AnimatorSet set = new AnimatorSet(); set.setDuration(1000); set.playTogether(animator1, animator2, animator3); set.start();
AnimatorSet中有一系列的順序控制方法:playTogether、playSequentially、animSet.play().with()、defore()、after()等。用來實現多個動畫的協同工作方式。
public void scaleX(View view)
{
// 加載動畫
Animator anim = AnimatorInflater.loadAnimator(this, R.animator.scalex);
anim.setTarget(mMv);
anim.start();
}
布局動畫是指ViewGroup在布局時產生的動畫效果

package com.example.animtest;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.Keyframe;
import android.animation.LayoutTransition;
import android.animation.ObjectAnimator;
import android.animation.PropertyValuesHolder;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.LinearLayout;
public class AnimateLayoutTransition extends Activity {
private LinearLayout ll;
private LayoutTransition mTransition = new LayoutTransition();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.animate_layout_transition);
ll = (LinearLayout) findViewById(R.id.ll);
setupCustomAnimations();
ll.setLayoutTransition(mTransition);
}
public void add(View view) {
final Button button = new Button(this);
ll.addView(button);
button.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
ll.removeView(button);
}
});
}
// 生成自定義動畫
private void setupCustomAnimations() {
// 動畫:CHANGE_APPEARING
// Changing while Adding
PropertyValuesHolder pvhLeft = PropertyValuesHolder.ofInt(left, 0, 1);
PropertyValuesHolder pvhTop = PropertyValuesHolder.ofInt(top, 0, 1);
PropertyValuesHolder pvhRight = PropertyValuesHolder.ofInt(right, 0,
1);
PropertyValuesHolder pvhBottom = PropertyValuesHolder.ofInt(bottom,
0, 1);
PropertyValuesHolder pvhScaleX = PropertyValuesHolder.ofFloat(scaleX,
1f, 0f, 1f);
PropertyValuesHolder pvhScaleY = PropertyValuesHolder.ofFloat(scaleY,
1f, 0f, 1f);
final ObjectAnimator changeIn = ObjectAnimator.ofPropertyValuesHolder(
this, pvhLeft, pvhTop, pvhRight, pvhBottom, pvhScaleX,
pvhScaleY).setDuration(
mTransition.getDuration(LayoutTransition.CHANGE_APPEARING));
mTransition.setAnimator(LayoutTransition.CHANGE_APPEARING, changeIn);
changeIn.addListener(new AnimatorListenerAdapter() {
public void onAnimationEnd(Animator anim) {
View view = (View) ((ObjectAnimator) anim).getTarget();
// View也支持此種動畫執行方式了
view.setScaleX(1f);
view.setScaleY(1f);
}
});
// 動畫:CHANGE_DISAPPEARING
// Changing while Removing
Keyframe kf0 = Keyframe.ofFloat(0f, 0f);
Keyframe kf1 = Keyframe.ofFloat(.9999f, 360f);
Keyframe kf2 = Keyframe.ofFloat(1f, 0f);
PropertyValuesHolder pvhRotation = PropertyValuesHolder.ofKeyframe(
rotation, kf0, kf1, kf2);
final ObjectAnimator changeOut = ObjectAnimator
.ofPropertyValuesHolder(this, pvhLeft, pvhTop, pvhRight,
pvhBottom, pvhRotation)
.setDuration(
mTransition
.getDuration(LayoutTransition.CHANGE_DISAPPEARING));
mTransition
.setAnimator(LayoutTransition.CHANGE_DISAPPEARING, changeOut);
changeOut.addListener(new AnimatorListenerAdapter() {
public void onAnimationEnd(Animator anim) {
View view = (View) ((ObjectAnimator) anim).getTarget();
view.setRotation(0f);
}
});
// 動畫:APPEARING
// Adding
ObjectAnimator animIn = ObjectAnimator.ofFloat(null, rotationY, 90f,
0f).setDuration(
mTransition.getDuration(LayoutTransition.APPEARING));
mTransition.setAnimator(LayoutTransition.APPEARING, animIn);
animIn.addListener(new AnimatorListenerAdapter() {
public void onAnimationEnd(Animator anim) {
View view = (View) ((ObjectAnimator) anim).getTarget();
view.setRotationY(0f);
}
});
// 動畫:DISAPPEARING
// Removing
ObjectAnimator animOut = ObjectAnimator.ofFloat(null, rotationX, 0f,
90f).setDuration(
mTransition.getDuration(LayoutTransition.DISAPPEARING));
mTransition.setAnimator(LayoutTransition.DISAPPEARING, animOut);
animOut.addListener(new AnimatorListenerAdapter() {
public void onAnimationEnd(Animator anim) {
View view = (View) ((ObjectAnimator) anim).getTarget();
view.setRotationX(0f);
}
});
}
}


package com.example.animtest;
import android.app.Activity;
import android.os.Bundle;
import android.view.animation.LayoutAnimationController;
import android.view.animation.ScaleAnimation;
import android.widget.LinearLayout;
public class AnimateLayoutAnimation extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.animate_layout_animation);
LinearLayout ll = (LinearLayout) findViewById(R.id.ll);
ScaleAnimation sa = new ScaleAnimation(0, 1, 0, 1);
sa.setDuration(2000);
// 第二個參數dely : the delay by which each child's animation must be offset
LayoutAnimationController lac = new LayoutAnimationController(sa, 0.5F);
// 設置顯示的順序 這個必須要在dely不為0的時候才有效
lac.setOrder(LayoutAnimationController.ORDER_NORMAL);
ll.setLayoutAnimation(lac);
}
}
view.animate().alpha(0).y(100).setDuration(1000)
.withStartAction(new Runnable() {
@Override
public void run() {
}
}).withEndAction(new Runnable() {
@Override
public void run() {
runOnUiThread(new Runnable() {
@Override
public void run() {
}
});
}
}).start();
public class FloatEvaluator implements TypeEvaluator {
public Object evaluate(float fraction, Object startValue,
Object endValue) {
float startFloat = ((Number) startValue).floatValue();
return startFloat + fraction
* (((Number) endValue).floatValue() - startFloat);
}
}
Keyframe kf0 = Keyframe.ofInt(0, 400); Keyframe kf1 = Keyframe.ofInt(0.25f, 200); Keyframe kf2 = Keyframe.ofInt(0.5f, 400); Keyframe kf4 = Keyframe.ofInt(0.75f, 100); Keyframe kf3 = Keyframe.ofInt(1f, 500); PropertyValuesHolder pvhRotation = PropertyValuesHolder.ofKeyframe(width, kf0, kf1, kf2, kf4, kf3); ObjectAnimator rotationAnim = ObjectAnimator.ofPropertyValuesHolder(btn2, pvhRotation); rotationAnim.setDuration(2000);
ObjectAnimator oa=ObjectAnimator.ofInt(btn2, width, 400,200,400,100,500); oa.setDuration(2000); oa.start();
Android自定義View實現隨機驗證碼
對於android開發來說自定義View還是一個比較重要的技能,所以在這裡寫一篇自定義View入門的文章,也是實現一個相對簡單的隨機產生驗證碼的功能: 自定義View主要
Android基於Service的音樂播放器
本文開發一個基於Service的音樂播放器,音樂由後台運行的Service負責播放,當後台的播放狀態發生變化時,程序將會通過發送廣播通知前台Activity更新界面;當點
android百度地圖 添加覆蓋物Marker與InfoWindow的使用
如何添加覆蓋物,實現周邊搜索,以及對覆蓋物的點擊出現介紹等效果。效果圖:我們的需求是,當用戶點擊衣食住行,或者對對附近搜索是,從服務器返回數據(經緯度,商家信息,介紹等)
GreenDao 3.2.0 的基本使用
前言Android開發中我們或多或少都會接觸到數據庫。Android中提供了一個占用內存極小的關系型數據庫-SQLite。雖然Android系統中提供了許多操作SQLit