Android SpringAnimation 安卓模擬彈簧動畫

前言

在最近的Support Library更新中(25.3.0),新增或者修復了許多東西,具體可以看revisions,其中有一個新增的動畫效果:SpringAnimation 即彈簧動畫,隨即,Android 開發者發布了一段簡短的gistHere,演示了該動畫庫的簡單使用。並在一個不存在的網站上post出gif演示:

由於大神給出的代碼不是很完整,出於好奇的心態,於是在gist的基礎上復現了一下該效果,方便參考。

SpringAnimation

SpringAnimation是一個受SpringForce驅動的動畫。彈簧力限定了彈簧的剛度,阻尼比以及靜止位置。一旦彈簧動畫開始,在每一幀上,彈簧力將更新動畫的值和速度。動畫一直運行,直到彈力達到平衡。如果在動畫中使用了無阻尼的彈簧,動畫將永遠不會達到平衡,永遠振蕩下去。。。

該類提供了以下方法:

代碼示例

public class MainActivity extends Activity {nn //XY坐標n private float downX, downY;n //調整參數的SeekBarn private SeekBar dampingSeekBar, stiffnessSeekBar;n //X/Y方向速度相關的幫助類n private VelocityTracker velocityTracker;nn @Overriden protected void onCreate(Bundle savedInstanceState) {n super.onCreate(savedInstanceState);n setContentView(R.layout.activity_main);n findViewById(android.R.id.content).setSystemUiVisibility(n View.SYSTEM_UI_FLAG_LAYOUT_STABLEn | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREENn | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION);n stiffnessSeekBar = (SeekBar) findViewById(R.id.stiffness);n dampingSeekBar = (SeekBar) findViewById(R.id.damping);n velocityTracker = VelocityTracker.obtain();n final View box = findViewById(R.id.box);n findViewById(R.id.content).setOnTouchListener(new View.OnTouchListener() {n @Overriden public boolean onTouch(View v, MotionEvent event) {n switch (event.getAction()) {n case MotionEvent.ACTION_DOWN:n downX = event.getX();n downY = event.getY();n velocityTracker.addMovement(event);n return true;n case MotionEvent.ACTION_MOVE:n box.setTranslationX(event.getX() - downX);n box.setTranslationY(event.getY() - downY);n velocityTracker.addMovement(event);n return true;n case MotionEvent.ACTION_UP:n case MotionEvent.ACTION_CANCEL:n velocityTracker.computeCurrentVelocity(1000);n if (box.getTranslationX() != 0) {n SpringAnimation animX = new SpringAnimation(box, SpringAnimation.TRANSLATION_X, 0);n animX.getSpring().setStiffness(getStiffnessSeekBar());n animX.getSpring().setDampingRatio(getDampingSeekBar());n animX.setStartVelocity(velocityTracker.getXVelocity());n animX.start();n }n if (box.getTranslationY() != 0) {n SpringAnimation animY = new SpringAnimation(box, SpringAnimation.TRANSLATION_Y, 0);n animY.getSpring().setStiffness(getStiffnessSeekBar());n animY.getSpring().setDampingRatio(getDampingSeekBar());n animY.setStartVelocity(velocityTracker.getYVelocity());n animY.start();n }n velocityTracker.clear();n return true;n }n return false;n }n });n }nn /**n * 從SeekBar獲取自定義的強度n *n * @return 強度floatn */n private float getStiffnessSeekBar() {n return Math.max(stiffnessSeekBar.getProgress(), 1f);n }nn /**n * 從SeekBar獲取自定義的阻尼n *n * @return 阻尼floatn */n private float getDampingSeekBar() {n return dampingSeekBar.getProgress() / 100f;n }n}n

關鍵方法:

SpringAnimation animX = new SpringAnimation(box, SpringAnimation.TRANSLATION_X, 0);n

查一下文檔,這個構造方法的參數是什麼意思?

  1. 第一個參數肯定是View啦,但是需要說明的是,這個動畫將會改變View的所有屬性,不僅僅是位置。
  2. 第二個參數是視圖的屬性索引;
  3. 第三個參數是彈簧被創建的最後位置

至於這個動畫庫的用途呢,就看開發者的想像力了。其他詳情看源碼,不多說了。

demo 演示:

最後

按照國際慣例,最重要的是附上完整源碼SpringAnimation 。喜歡的話請star一個!

推薦閱讀:

移動端項目踩到的坑及解決方案
Unity Android下Streaming Assets特殊姿勢

TAG:Android开发 | Android |