Reveal Effect用のライブラリ作りました



Android 5.0から追加された *Reveal Effect* というアニメーションがあります。

![topeka](http://cl.ly/image/1C1u343b433w/topeka.gif)
（上記の画像はGoogleが公開している[android-topeka](https://github.com/googlesamples/android-topeka)サンプルアプリです）


こんな感じでViewの切り替えをかっこよくできるもので、上手く使えばアプリをおしゃれにできてよさそうですね。

公式のリファレンスにこのアニメーションの適用方法があります（ソースコード抜粋）。

* [Reveal Effect](https://developer.android.com/training/material/animations.html#Reveal)

```java
// previously invisible view
View myView = findViewById(R.id.my_view);

// get the center for the clipping circle
int cx = (myView.getLeft() + myView.getRight()) / 2;
int cy = (myView.getTop() + myView.getBottom()) / 2;

// get the final radius for the clipping circle
int finalRadius = Math.max(myView.getWidth(), myView.getHeight());

// create the animator for this view (the start radius is zero)
Animator anim =
    ViewAnimationUtils.createCircularReveal(myView, cx, cy, 0, finalRadius);

// make the view visible and start the animation
myView.setVisibility(View.VISIBLE);
anim.start();
```

上記の処理は、ビューを円形にクリッピングするための中心などを計算し、それを基にアニメーターを作ってからアニメーションスタートしているような流れです。

アニメーションというと *ViewPropertyAnimator* がありますが、こちらはメソッドチェーンできてスマートにかけますね。 
*Reveal Effect* を適用するときもそんな感じで書けるようにしたかったので、ライブラリを作ってみました。

ライブラリはGitHubにありますのでよろしければ使ってみてください。

* [GitHub](https://github.com/droibit/clippin)

以下は簡単な使い方になります。

## 使い方

### 導入

アプリモジュールなどの *build.gradle* に次のコードを追加します。

```
repositories {
    maven { url "https://jitpack.io" }
}

dependencies {
    compile 'com.github.droibit:clippin:1.0.1'
}
```

### アニメーション

最小のコードは次のようになります。

```java
View targetView = ...;	// アニメーション対象のビューの作成
Clippin.animate().target(targetView)
		 .center(Clippin.CENTER_LEFT_TOP)
		 .show(null);
```

使い方はアニメーション対象のビューを用意して、付加的な情報をメソッドチェーンしながら追加していきます。

円の中心にはビュー矩形の中心や四隅など、ライブラリ側で用意した定数を指定します。

```java
Clippin.animate().center(Clippin.CENTER_LEFT_TOP)
		 			// or
		 		   .center(Clippin.CENTER_RIGHT_BOTTOM)
		 		   // or
		 		   .center(Clippin.CENTER_ORIGIN)
		 		   // などなど		

```

他にもtopekaのようにFloating Action Buttonを中心にアニメーションしたい時は次のようになります。

```java
final View fab = findViewById(R.id.fab)
Clippin.animate().center(fab);

```

そして末尾の `#show()` or `#hide()` メソッドを呼ぶとアニメーションが開始します。
*show* を呼んだ場合は円が広がっていくアニメーションで、 *hide* を読んだ場合は円が狭まっていくようなアニメーションになります。
アニメーションが終了したタイミングで何か処理をしたい場合はコールバックが設定できるようになっています。

```java
Clippin.animate().target(targetView)
		 // 略
		 .show(null)
		 // or
		 .hide(new Clippin.Callback() {
            @Override public void onAnimationEnd() {
                Toast.makeText(getActivity(), "Hide ...", Toast.LENGTH_SHORT).show();            
            }
        }); 
```

他のオプションも含めて全てパラメータを指定するとこんなかんじです。

```java
final View targetView = ...;
Clippin.animate().target(tagetView)
				   .center(Clippin.CENTER_LEFT_TOP)
				   .duration(750)	// アニメーションする時間（ミリ秒)
				   .startDelay(100) // 開始遅延（ミリ秒）
				   .interpolator(new AccelerateDecelerateInterpolator()) // 補間方法
				   .show(new Clippin.Callback() {
            			@Override public void onAnimationEnd() {
                			Toast.makeText(getActivity(), "Hide ...", Toast.LENGTH_SHORT).show();            
            			}
        			}); 
```

*Reveal Effect* はAndroid5.0から導入されたアニメーションなので4.4以下では使えませんが、
`Build.VERSION.SDK_INT` で分岐しなくても大丈夫なようになっています。アニメーションのパラメータは全て無視されますが、`#show()` or `#hide()` 呼んだ結果は同じになりますし、コールバックも呼ばれますので上記のようなコードのまま使えます。

## おまけ

 *kotlin* を使用している方向けです。kotlinは拡張関数が使用できますので、 Viewにアニメーション用のメソッドを追加することができます。

```kotlin
/**
 * Shortcut of the [Clippin.animate().target(view)].
 */
public fun View.clip(): ClippingAnimator = Clippin.animate().target(this)
 
// call example
val view = ... // create view
view.clip().circleCenter(Clippin.CENTER_LEFT_BOTTOM)
           .duration(600)
           .show {
               Toast.makeText(context, "Show", Toast.LENGTH_SHORT).show()
           }
```

これで *View#animate()* と同じように使えますね！