介绍Facebook的rebound动画库

转:点击打开链接

Rebound是Facebook推出的一款Android的物理和动画库,于2013年10月在Mobile@Scale大会上正式发布,旨在解决笨重、缓慢的传统移动网络界面。在其Rebound官方主页可以体验基于js版构建的Rebound效果

Rebound不是一款通用物理库,但其弹簧模型在应用程序中引入了现实世界的物理,易于集成,创建的动画能够让人感觉到非常自然,并且可以和Material Design的设计原则呼应,可用于滚动条、切换开关、呼叫等场景下。下面看一下如何在Android上实现和官方网页一样的演示效果:

(PS:完整代码放在博文最后)

1.首先添加Rebound库依赖

Rebound提供了三种方式引入,当然在Android Studio下还是推荐使用Gradle方式。

  • 添加Gradle依赖(推荐)
     
     
1
2
3
     
     
dependencies {
compile 'com.facebook.rebound:rebound:0.3.6'
}
     
     
1
2
3
4
5
     
     
<dependency>
<groupId>com.facebook.rebound </groupId>
<artifactId>rebound </artifactId>
<version>0.3.6 </version>
</dependency>

2.首先创建一个SpringSystem对象

     
     
1
     
     
SpringSystem mSpringSystem = SpringSystem.create();

3.添加一个“弹簧”到系统

     
     
1
     
     
Spring mSpring = mSpringSystem.createSpring();

4.添加监听器

     
     
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
     
     
mSpring.addListener( this);
//实现SpringListener接口,需要实现下面方法
@Override
public void onSpringUpdate(Spring spring) {
}
@Override
public void onSpringAtRest(Spring spring) {
}
@Override
public void onSpringActivate(Spring spring) {
}
@Override
public void onSpringEndStateChange(Spring spring) {
}

5.设置动画结束值

     
     
1
     
     
mSpring.setEndValue( 1f);

6.在弹簧更新数据是对图片进行对应伸缩

     
     
1
2
3
4
5
6
     
     
public void onSpringUpdate(Spring spring) {
float value = ( float) spring.getCurrentValue();
float scale = 1f - (value * 0.5f);
mImageToAnimate.setScaleX(scale);
mImageToAnimate.setScaleY(scale);
}

通过上面几个步骤可以很方便的实现弹簧阻尼效果的图片伸缩,当然还加入SeekBar用于更新系数,具体实现细节查看完整代码。

效果如下:

完整代码:

布局文件

     
     
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
     
     
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools= "http://schemas.android.com/tools"
android:layout_width= "match_parent"
android:layout_height= "match_parent"
tools:context= ".MainActivity">
<ImageView
android:layout_width= "wrap_content"
android:layout_height= "wrap_content"
android:id= "@+id/imageView"
android:layout_marginTop= "100dp"
android:src= "@drawable/rebound"
android:layout_centerHorizontal= "true" />
<LinearLayout
android:orientation= "horizontal"
android:id= "@+id/llTension"
android:layout_width= "fill_parent"
android:layout_height= "wrap_content"
android:layout_below= "@+id/imageView"
android:layout_centerHorizontal= "true"
android:layout_marginTop= "100dp">
<TextView
android:layout_width= "wrap_content"
android:layout_height= "wrap_content"
android:text= "张力系数: "
android:textSize= "18sp"
android:layout_gravity= "center"
android:layout_marginLeft= "50dp"
android:id= "@+id/tvTension" />
<SeekBar
android:layout_width= "fill_parent"
android:layout_height= "wrap_content"
android:id= "@+id/skTension" />
</LinearLayout>
<LinearLayout
android:orientation= "horizontal"
android:layout_width= "fill_parent"
android:layout_below= "@id/llTension"
android:layout_height= "wrap_content">
<TextView
android:layout_width= "wrap_content"
android:layout_height= "wrap_content"
android:text= "阻力系数: "
android:textSize= "18sp"
android:layout_marginLeft= "50dp"
android:layout_gravity= "center"
android:id= "@+id/tvFriction" />
<SeekBar
android:layout_width= "fill_parent"
android:layout_height= "wrap_content"
android:id= "@+id/skFriction" />
</LinearLayout>
</RelativeLayout>

MainActivity.java

     
     
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
     
     
public class MainActivity extends Activity implements View.OnTouchListener, SpringListener {
private int tension = 40; //张力系数
private int friction = 3; //阻力系数
private ImageView ivScalaImage;
private SpringSystem mSpringSystem;
private Spring mSpring;
private SeekBar skTension,skFriction;
private TextView tvTension,tvFriction;
private SBListener sbListener;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//初始化控件
initWidget();
//创建系统用于循环执行控件弹簧效果
mSpringSystem = SpringSystem.create();
//给系统添加一个“弹簧”
mSpring = mSpringSystem.createSpring();
//添加监听器,监听“弹簧”的形变
mSpring.addListener( this);
//根据张力系数和阻力系数创建一组“弹簧”参数
SpringConfig config = new SpringConfig(tension, friction);
//配置“弹簧”
mSpring.setSpringConfig(config);
}
private void initWidget() {
ivScalaImage = (ImageView) findViewById(R.id.imageView);
ivScalaImage.setOnTouchListener( this);
skTension = (SeekBar) findViewById(R.id.skTension);
skFriction = (SeekBar) findViewById(R.id.skFriction);
sbListener = new SBListener();
skTension.setMax( 100);
skFriction.setMax( 30);
skTension.setOnSeekBarChangeListener(sbListener);
skFriction.setOnSeekBarChangeListener(sbListener);
tvTension = (TextView) findViewById(R.id.tvTension);
tvFriction = (TextView) findViewById(R.id.tvFriction);
skTension.setProgress(tension);
skFriction.setProgress(friction);
tvTension.setText( "张力系数: " + tension);
tvFriction.setText( "阻力系数: "+friction);
}
@Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
mSpring.setEndValue( 1f);
return true;
case MotionEvent.ACTION_UP:
mSpring.setEndValue( 0f);
return true;
}
return false;
}
@Override
public void onSpringUpdate(Spring spring) {
float value = ( float) spring.getCurrentValue();
float scale = 1f - (value * 0.5f);
ivScalaImage.setScaleX(scale);
ivScalaImage.setScaleY(scale);
}
@Override
public void onSpringAtRest(Spring spring) {
SpringConfig config = new SpringConfig(tension, friction);
mSpring.setSpringConfig(config);
}
@Override
public void onSpringActivate(Spring spring) {
}
@Override
public void onSpringEndStateChange(Spring spring) {
}
private class SBListener implements SeekBar.OnSeekBarChangeListener {
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
if (seekBar.getId() == R.id.skTension){
tension = progress;
skTension.setProgress(tension);
tvTension.setText( "张力系数: " + tension);
} else if (seekBar.getId() == R.id.skFriction){
friction = progress;
skFriction.setProgress(friction);
tvFriction.setText( "阻力系数: "+friction);
}
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
mSpring.setAtRest();
}
}
}
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值