Spring Animations for Android
- Rebound is a java library that models spring dynamics. Rebound spring models can be used to create animations that feel natural by introducing real world physics to your application胖替。rebound是Facebook的一個(gè)動(dòng)畫庫,rebound就是使動(dòng)畫更加符合現(xiàn)實(shí)生活的情景。
- 在 http://facebook.github.io/rebound/上可以通過點(diǎn)擊圖片感受一下動(dòng)畫效果营勤。它的效果受到tension(張力)稠曼,friction(摩擦力)影響绍傲,通過生活中的體驗(yàn)以及調(diào)節(jié)兩個(gè)值我們可以體驗(yàn)到不同的動(dòng)畫效果荠耽,tension的值越大,friction 的值越小效果就越明顯,反之相反气嫁。
使用
首先添加依賴
dependencies {
compile 'com.facebook.rebound:rebound:0.3.8'
}
參考官方demo 寫的簡(jiǎn)單圖片縮放例子
private final View mImageView;
SpringSystem springSystem = SpringSystem.create();
Spring spring = springSystem.createSpring();
spring.addListener(new SimpleSpringListener() {
@Override
public void onSpringUpdate(Spring spring) {
// 在這里可以根據(jù)自己的需求設(shè)置view 的動(dòng)畫效果
//下面方法通過spring 得到currentvalue
double value=spring.getCurrentValue()简识;
float mappedValue = (float) SpringUtil.mapValueFromRangeToRange(value, 0, 1, 1, 0.5);
mImageView.setScaleX(mappedValue);
mImageView.setScaleY(mappedValue);
}
});
mImageView.setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
spring.setEndValue(1);//設(shè)置靜止時(shí)候的值為1
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
spring.setEndValue(0);
break;
}
return true;
}
});
在onSpringUpdate的回調(diào)中的mapValueFromRangeToRange(double value,double fromLow,double fromHigh,double toLow,double toHigh)
SpringUtil 是庫中的工具類,從方法名可以開出是一個(gè)映射關(guān)系道盏,把當(dāng)前value值從0~1映射到1~0.5中去伟葫。
當(dāng)按下的時(shí)候我們?cè)O(shè)置為1,對(duì)應(yīng)到0.5弛槐,所以完全按下后圖片會(huì)縮小至0.5倍,抬起反之逾柿,中間的狀態(tài)就是通過不斷變化的value 值確定璧亮。
我們可以通過設(shè)置Spring的張力和摩擦力
mScaleSpring.setSpringConfig(new SpringConfig(40,1.4));改變動(dòng)畫效果镀裤。
多個(gè)動(dòng)畫聯(lián)動(dòng)效果
通過SpringChain
package com.example.wys.rebound;
import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.View;
import android.widget.ImageView;
import com.example.wys.rebound.app.PlaygroundActivity;
import com.facebook.rebound.SimpleSpringListener;
import com.facebook.rebound.Spring;
import com.facebook.rebound.SpringChain;
import com.facebook.rebound.SpringSystem;
import com.facebook.rebound.SpringUtil;
import java.util.ArrayList;
public class MainActivity extends AppCompatActivity {
private ImageView imageView1,imageView2,imageView3,imageView4;
private SpringChain springChain;
private SpringSystem springSystem;
private ArrayList<ImageView> imageViews=new ArrayList<>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
}
private void initView() {
springSystem=SpringSystem.create();
springChain=SpringChain.create();
imageView1= (ImageView) findViewById(R.id.image1);
imageView2= (ImageView) findViewById(R.id.image2);
imageView3= (ImageView) findViewById(R.id.image3);
imageView4= (ImageView) findViewById(R.id.image4);
imageViews.add(imageView1);
imageViews.add(imageView2);
imageViews.add(imageView3);
imageViews.add(imageView4);
for (int i=0;i<imageViews.size();i++){
final int finalI = i;
springChain.addSpring(new SimpleSpringListener(){
@Override
public void onSpringUpdate(Spring spring) {
float v = (float) SpringUtil.mapValueFromRangeToRange(spring.getCurrentValue(), 0, 1, 1, 0.7);
imageViews.get(finalI).setScaleX(v);
imageViews.get(finalI).setScaleY(v);
}
});
imageViews.get(i).setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View view, MotionEvent motionEvent) {
int action = motionEvent.getAction();
switch (action){
case MotionEvent.ACTION_DOWN:
springChain.setControlSpringIndex(finalI).getControlSpring().setEndValue(1);
break;
case MotionEvent.ACTION_CANCEL:
case MotionEvent.ACTION_UP:
springChain.getControlSpring().setEndValue(0);
break;
}
return true;
}
});
}
}
public void play(View view){
startActivity(new Intent(this, PlaygroundActivity.class));
}
}
我們要對(duì)每個(gè)view設(shè)置Spring通過springChain.addSpring添加纺且。
SpringChain 實(shí)現(xiàn)了SpringListener 接口载碌,含有一個(gè)Spring集合步咪,一個(gè)SpringListener集合,在addSpring代碼實(shí)現(xiàn)
public SpringChain addSpring(final SpringListener listener) {
// We listen to each spring added to the SpringChain and dynamically chain the springs together
// whenever the control spring state is modified.
Spring spring = mSpringSystem
.createSpring()
.addListener(this)
.setSpringConfig(mAttachmentSpringConfig);
mSprings.add(spring);
mListeners.add(listener);
return this;
}
多個(gè)動(dòng)畫聯(lián)動(dòng)魚單個(gè)不同的是需要指定第幾個(gè)view做為帶頭的那個(gè)悯周,通過springChain.setControlSpringIndex(finalI).getControlSpring().setEndValue(1);
這樣就實(shí)現(xiàn)了多個(gè)動(dòng)畫一起聯(lián)通的效果。如果需要其他的動(dòng)效的話可以自己實(shí)現(xiàn),rebound 的整體用法還是比較簡(jiǎn)單的生均。