ExplosionField簡單分析

weixin_34146805發表於2017-03-05

首先來個傳送門吧

https://github.com/tyrantgit/ExplosionField


先來看看怎麼使用吧(比較簡單)

  • 首先獲取到ExplosionField例項
ExplosionField.attach2Window(this);
  • 接著就是呼叫了撒
 mExplosionField.explode(v);
  • 看看實現效果吧 _ ( 盜用作者的圖哈~~)
    4203910-bcf36b9c6d1b8c2b.gif
    作者最後的效果圖 哈哈

原始碼分析

  • 吧原始碼搞下來 (~~就只用3個類 哈哈)
4203910-249d39ddf41b7bbc.png
原始碼結構截圖
  • 首先來看attach方法 ExplosionField.attach2Window(this)
public static ExplosionField attach2Window(Activity activity) {
        ViewGroup rootView = (ViewGroup) activity.findViewById(
                                  Window.ID_ANDROID_CONTENT);
        ExplosionField explosionField = new ExplosionField(activity);
        rootView.addView(explosionField, 
                         new ViewGroup.LayoutParams(
                              ViewGroup.LayoutParams.MATCH_PARENT,
                              ViewGroup.LayoutParams.MATCH_PARENT)
        );
        return explosionField;
    }
  • 這個Window.ID_ANDROID_CONTENT,稍微解釋哈,我們setContentView的時候就其實就是吧我們的佈局新增到一個FrameLayout裡面,而這個FrameLayout的id就是android.R.id.content

    4203910-581aa006f2a92765.png
    content_id

  • 最後在ContentView裡面新增一個ExplosionField控制元件,並且把這個控制元件返回給呼叫著。

  • 接下來看看呼叫這個控制元件ExplosionField怎麼實現的

    • 首先在構造方法裡面呼叫了init方法,就是初始化了一個int陣列,初始化的值都是32dp

private int[] mExpandInset = new int[2];
private void init() {
Arrays.fill(mExpandInset, Utils.dp2Px(32));
}


- onDraw方法,可以看到就是遍歷了一個集合並呼叫了集合元素的draw方法。
```java
private List<ExplosionAnimator> mExplosions = new ArrayList<>();
@Override
  protected void onDraw(Canvas canvas) {
      super.onDraw(canvas);
      for (ExplosionAnimator explosion : mExplosions) {
          explosion.draw(canvas);
      }
  }
  • 初始化和onDraw方法都看完了,現在來看看呼叫的explode方法。其實就是獲取控制元件的位置,然後構造了一個ValueAnimator,最後呼叫了start方法
public void explode(final View view) {
        Rect r = new Rect();
        view.getGlobalVisibleRect(r);
        int[] location = new int[2];
        getLocationOnScreen(location);
        r.offset(-location[0], -location[1]);
        r.inset(-mExpandInset[0], -mExpandInset[1]);
        int startDelay = 100;
        ValueAnimator animator = ValueAnimator.ofFloat(0f, 1f).setDuration(150);
        animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {

            Random random = new Random();

            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                view.setTranslationX((random.nextFloat() - 0.5f) * view.getWidth() * 0.05f);
                view.setTranslationY((random.nextFloat() - 0.5f) * view.getHeight() * 0.05f);

            }
        });
        animator.start();
        view.animate().setDuration(150).setStartDelay(startDelay).scaleX(0f).scaleY(0f).alpha(0f).start();
        explode(Utils.createBitmapFromView(view), r, startDelay, ExplosionAnimator.DEFAULT_DURATION);
    }
```java
  public void explode(Bitmap bitmap, Rect bound, long startDelay, long duration) {
    final ExplosionAnimator explosion = new ExplosionAnimator(this, bitmap, bound);
    explosion.addListener(new AnimatorListenerAdapter() {
        @Override
        public void onAnimationEnd(Animator animation) {
            mExplosions.remove(animation);
        }
    });
    explosion.setStartDelay(startDelay);
    explosion.setDuration(duration);
    mExplosions.add(explosion);
    explosion.start();
}
- 最後看看比較取巧的一個執行動畫的方法,在view的onDraw方法呼叫ValueAnimator的draw方法,ValueAnimator的draw方法在去呼叫View的invalidate方法。
```java
public boolean draw(Canvas canvas) {
      if (!isStarted()) {
          return false;
      }
      for (Particle particle : mParticles) {
          particle.advance((float) getAnimatedValue());
          if (particle.alpha > 0f) {
              mPaint.setColor(particle.color);
              mPaint.setAlpha((int) (Color.alpha(particle.color) * particle.alpha));
              canvas.drawCircle(particle.cx, particle.cy, particle.radius, mPaint);
          }
      }
      mContainer.invalidate();
      return true;
  }

Nothing is certain in this life. The only thing i know for sure is that. I love you and my life. That is the only thing i know. have a good day

:)

相關文章