Rebound动画框架简单介绍

现在主要是来分析下Rebound的源码,看看里面到底怎么走的,用法很简单(这是最简单的用法),就三句话:

SpringSystem springSystem = SpringSystem.create();
spring = springSystem.createSpring();
spring.addListener(new SpringListener() {}



最近在接手了一个老项目,发现里面动画框架用的是facebook中的Rebound框架,由于以前没听说过,放假时闲得蛋痛,看看了源码,就顺手写这一篇吧。 
写了一个小Demo,具体效果如下: 
这是图片啊 

代码很简单,这是xml布局:

<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"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context=".MainActivity" >

    <ImageView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/image"
        android:src="@drawable/a1" />

</RelativeLayout>

这是MainActivity:

package com.micro.mytest_button;

import android.app.Activity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.widget.ImageView;

import com.facebook.rebound.Spring;
import com.facebook.rebound.SpringListener;
import com.facebook.rebound.SpringSystem;
import com.nineoldandroids.view.ViewHelper;

public class MainActivity extends Activity {

    private ImageView image;
    private Spring spring;

    private final float mScale = 1.0f;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        image = (ImageView) findViewById(R.id.image);

        SpringSystem springSystem = SpringSystem.create();
        spring = springSystem.createSpring();       
        spring.addListener(new SpringListener() {

            @Override
            public void onSpringUpdate(Spring spring) {
                float value = (float) spring.getCurrentValue();
                float scale = 1f - (value * mScale);

                System.out.println("the value is " + value + "--the scale is --" + scale);

                ViewHelper.setScaleX(image, scale);
                ViewHelper.setScaleY(image, scale);
            }

            @Override
            public void onSpringEndStateChange(Spring spring) {
            }

            @Override
            public void onSpringAtRest(Spring spring) {
            }

            @Override
            public void onSpringActivate(Spring spring) {
            }
        });

        image.setOnTouchListener(new OnTouchListener() {

            @Override
            public boolean onTouch(View v, MotionEvent event) {
                switch (event.getAction()) {
                case MotionEvent.ACTION_DOWN:
                    spring.setEndValue(1.0f);
                    break;

                case MotionEvent.ACTION_UP:
                case MotionEvent.ACTION_CANCEL:
                    spring.setEndValue(0.0f);
                    break;
                }

                return true;
            }
        });
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

}

 

现在主要是来分析下Rebound的源码,看看里面到底怎么走的,用法很简单(这是最简单的用法),就三句话:

SpringSystem springSystem = SpringSystem.create();
spring = springSystem.createSpring();
spring.addListener(new SpringListener() {}

主要是创建了三个对象,SpringSystem/spring/SpringListener,对于动画的效果,就是这三个玩意搞出来的。具体的模式如下: 
SpringSystem:继承自BaseSpringSystem,其中包含了Spring对象引用的容器,控制Spring对象的操作,存在一个SpringLooper(是一个抽象方法,只有start()/stop()方法),这也是facebook自定义的类,与android.os.Looper无关,只是模拟了android.os.Looper的方法,内存start(),end()方法。其构造方法:

 public static SpringSystem create() {
    return new SpringSystem(AndroidSpringLooperFactory.createSpringLooper());
  }

 

打开SpringSystem(SpringLooper sl)源码:

  public BaseSpringSystem(SpringLooper springLooper) {
    if (springLooper == null) {
      throw new IllegalArgumentException("springLooper is required");
    }
    mSpringLooper = springLooper;
    mSpringLooper.setSpringSystem(this);
  }

 

现在再看AndroidSpringLooperFactory.createSpringLooper()源码:

 public static SpringLooper createSpringLooper() {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
      return ChoreographerAndroidSpringLooper.create();
    } else {
      return LegacyAndroidSpringLooper.create();
    }
  }

 

可以看到为了兼容JDK,高低版本创建的SpringLooper容器不经相同,这个不是考虑的重点。

现在来看第二句:

spring = springSystem.createSpring();

 

翻开SpringSytem.createSpring()源码:

 public Spring createSpring() {
    Spring spring = new Spring(this);
    registerSpring(spring);
    return spring;
  }

 

可以看到Spring类是一个对立的Java类,持有SpringSystem的引用,来看看Spring(SpringSystem ss)构造函数:

  Spring(BaseSpringSystem springSystem) {
    if (springSystem == null) {
      throw new IllegalArgumentException("Spring cannot be created outside of a BaseSpringSystem");
    }
    mSpringSystem = springSystem;
    mId = "spring:" + ID++;
    setSpringConfig(SpringConfig.defaultConfig);
  }

 

再看setSpringConfig(SpringConfig.defaultConfig)源码:

public Spring setSpringConfig(SpringConfig springConfig) {
    if (springConfig == null) {
      throw new IllegalArgumentException("springConfig is required");
    }
    mSpringConfig = springConfig;
    return this;
  }

 

也只是初始化一些参数,并没有有我们想要的源码(这里的意思就是我点击图片时,它为什么会有动画的意思),再看第三个方法吧:

spring.addListener(new SpringListener() {}

 

添加监听器,用的多的人就会有感觉,这个也不会有关键代码可以使我们图片有缩放效果,那么问题来了,看到facebook写的三句话,我们并没有找到动画缩放的想过函数啊,是不是有配置文件或者静态/动态代码块呢??找了很久,没有啊。那只有接下来再看image的代码了,在看到Image的绑定的onTouch事件上,看到了这句话:

    spring.setEndValue(1.0f);

啥也不说,进去看看再说吧:

posted @ 2017-06-23 15:02  我爱程序猿  阅读(233)  评论(0)    收藏  举报