React NativeでWallet風UIを実装する

Advent Calendar 2021, React Native

この記事は最終更新日から1年以上が経過しています。

この記事はレコチョク Advent Calendar 2021の10日目の記事となります。

レコチョク・ラボの松木です。
仕事では主にレコチョク・ラボの取り組みをサポートしたり検証のためのプロトタイプを作ったりしています。

2021年も残り少しですが、おうち時間で楽器を楽しむ方が増えたというデータもあり、今年から新しく楽器をはじめた方もいるのではないでしょうか。
私は以前からサンプリングというものに興味があったので、サンプラーとマイクを使った遊びをはじめました。

作ったもの

今回作ったものはReact Nativeアプリケーションで動作する以下のようなアニメーションになります。
https://snack.expo.dev/@y-matsuki/wallet-like-ui

解説

今回実装するUIは react-native-snap-carousel をベースに実装しています。
コンポーネントの利用方法は以下です。

今回の実装で重要なポイントを以下に列挙します。
その他の属性についてはドキュメントを参照ください。

名称 説明
data リストのデータ
renderItem データを元にReactコンポーネントを返す関数(今回はカードを返す)
itemHeight 今回はカードの高さ300に対して54を指定することで重なりを表現する
scrollInterpolator スクロール位置に応じた挙動をカスタマイズする
slideInterpolatedStyle スクロール位置に応じたスタイルをカスタマイズする

ドキュメントを参考にスクロールした際の挙動のカスタマイズします。「scrollInterpolator」についてはほぼそのまま利用したため「slideInterpolatedStyle」の話をします。

animatedValue.interpolate()」関数を用いてスクロール時のスタイルの挙動アニメーションを定義します。「inputRange」がリスト内でのカードの位置を表しており「outputRange」がそれに対応するカードのスタイルを表します。
ちなみに「outputRange」を全て「0」にすると以下のようになります。(itemHeight = 54のため高さ54のリストとして描画される)

「transform.translateY」は「コンポーネントのY座標の位置を移動する」ことを表しており「cardHeight * 1.2」は「カードの高さの1.2倍の長さ(画面下部に)移動する」という意味になります。
アクティブなカードの前後を少しずつ上下に移動させてあげることで、アクティブなカードにアクセントを付けたUIを作ることができます。

また、zIndexの部分を以下のよう指定すると、カードの重なり順を逆にできます。

まとめ

iOSだとヌルヌル動くのですがAndroidの場合はshadowが効かなかったり動きが硬い感じでややイマイチでした。
今回の実装方法だとカードの枚数が多いとメモリを食うので、RecyclerView的な実装に改善するとより実用的と思います。

明日のレコチョク Advent Calendar 2021は11日目「家計簿のデータをNode.jsでスプレッドシート連携してみた」です。お楽しみに!