LayoutAnimationのススメ

in React Native

はじめに

この記事はmedium上でバズったJustin PoliachikによるReact Native’s LayoutAnimation is Awesome の翻訳記事です。全てのコード、画像、文章は全て許可を得て転載しており全ての権利は原著者に属します。

本編

LayoutAnimation を知らないReact Nativeエンジニアは間違いなく損をしています。

私は一端のiOSエンジニアとしてReact Nativeの世界に入り、最初こそCoreAnimationの様な利便性を失うのではないか、と心配でした。ネイティブのUIViewは素晴らしいもので適切なプロパティをviewにセットすれば期待通り動きます。一方でReact NativeのAnimated API も近いしい機能は備えており、良く出来ていますがそれぞれのアニメーションに対してstateを定義するのはコードがすぐに荒れますし、非常に複雑です。

そこでLayoutAnimationの出番です。ドキュメントが充実していないですが、安心してください。本当に素晴らしいです。

例えばn個のレイアウトの変更があった時、1行のコードでこのアニメーションを定義出来てしまいます。Viewがre-renderをする度にアニメーション部分をLayoutAnimationがよしなにハンドリングをしてくれます。大きくて複雑なviewsにとってこれは本当にPOWERFULです。

この例では3つのstateを持ちうる複雑なviewを用意しました。Heights, widths, and item countsはそれぞれ index stateによって決定されます。

上の例では一切のアニメーションが行われていないチープなアプリになっています。

// Called when a top button is pressed, with index corresponding to button title. 
onPress(index) {  
  this.setState({index: index});
}

それではこれにたった一行の LayoutAnimation のコードを加えて見ましょう。

LayoutAnimation.configureNext(LayoutAnimation.Presets.spring);

これによって全てのlayoutの変更に対して spring アニメーションが加えられるのです

sexyではないでしょうか?

// Called when a top button is pressed, with index corresponding to button title. 
onPress(index) {  
  LayoutAnimation.configureNext(LayoutAnimation.Presets.spring);
  this.setState({index: index});
}

3つのアニメーションが用意されています:

  • easeInEaseOut
  • linear
  • spring

もしくは以下の様に独自実装する事も可能です。

// Spring 
var CustomLayoutSpring = {  
    duration: 400,
    create: {
      type: LayoutAnimation.Types.spring,
      property: LayoutAnimation.Properties.scaleXY,
      springDamping: 0.7,
    },
    update: {
      type: LayoutAnimation.Types.spring,
      springDamping: 0.7,
    },
  };

// Linear with easing
var CustomLayoutLinear = {  
    duration: 200,
    create: {
      type: LayoutAnimation.Types.linear,
      property: LayoutAnimation.Properties.opacity,
    },
    update: {
      type: LayoutAnimation.Types.curveEaseInEaseOut,
    },
  };


 // Execute by calling before a state change
 // LayoutAnimation.configureNext(CustomLayoutSpring);

react-nativeの内部実装を見る限り、

LayoutAnimation はそれぞれのviewをユニークなキーによってアイデンティファイしそれらのre-render後の位置を計算します。そして native framework(iOSであればCoreAnimation)を用いてアニメーションを実行します。

Note: Android側の実装を追ってはないのでもしかすると微妙に異なるのかもしれません。

今回使用したコードはこちら

Comments