編輯:關於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還是一個比較重要的技能,所以在這裡寫一篇自定義View入門的文章,也是實現一個相對簡單的隨機產生驗證碼的功能: 自定義View主要
本文開發一個基於Service的音樂播放器,音樂由後台運行的Service負責播放,當後台的播放狀態發生變化時,程序將會通過發送廣播通知前台Activity更新界面;當點
如何添加覆蓋物,實現周邊搜索,以及對覆蓋物的點擊出現介紹等效果。效果圖:我們的需求是,當用戶點擊衣食住行,或者對對附近搜索是,從服務器返回數據(經緯度,商家信息,介紹等)
前言Android開發中我們或多或少都會接觸到數據庫。Android中提供了一個占用內存極小的關系型數據庫-SQLite。雖然Android系統中提供了許多操作SQLit