🏄‍♂️

React Native & ChatGPT モバイルアプリ開発(4)

2024/02/13に公開

スライドアニメーション

iOSではデフォルトの画面遷移がスライドですが、Androidではふわっと浮き上がってくるようなアニメーションになっています。これをAndroidでもスライドアニメーションに変更したいと思います。というのもこのあと左から右へのフリックで前の画面に戻るようにしたいので、指の動きと画面遷移を合わせたいからです。

  • カテゴリ一覧から板一覧への移動で、Androidでは左へスライドせずデフォルトの画面遷移となっています。また、板一覧からカテゴリ一覧へ戻るときも右へスライドせずデフォルトの画面遷移となっています。プラットフォームを問わずにスライドのアニメーションで画面遷移するように修正してください。
@@ -2,7 +2,7 @@
 
 import React from 'react';
 import { NavigationContainer } from '@react-navigation/native';
-import { createStackNavigator } from '@react-navigation/stack';
+import { createStackNavigator, CardStyleInterpolators } from '@react-navigation/stack';
 
 import CategoryListScreen from './CategoryListScreen';
 import BoardListScreen from './BoardListScreen';
@@ -13,7 +13,13 @@ const Stack = createStackNavigator<RootStackParamList>();
 const App = () => {
   return (
     <NavigationContainer>
-      <Stack.Navigator initialRouteName="CategoryList">
+      <Stack.Navigator
+        initialRouteName="CategoryList"
+        screenOptions={{
+          // 画面遷移アニメーションのカスタマイズ
+          cardStyleInterpolator: CardStyleInterpolators.forHorizontalIOS,
+        }}
+      >
         <Stack.Screen name="CategoryList" component={CategoryListScreen} options={{ title: 'カテゴリ一覧' }} />
         <Stack.Screen name="BoardList" component={BoardListScreen} options={{ title: '板一覧' }} />
       </Stack.Navigator>

なるほどね。cardStyleInterpolatorにforHorizontalIOSというオプションを指定するだけですか。こういうオプションがあるということはAndroidでもスライドさせたいというのは皆さん考えるということでしょうね。

  • 左から右へのフリックで板一覧画面からカテゴリ一覧画面に戻るように修正してください。
@@ -21,7 +21,16 @@ const App = () => {
         }}
       >
         <Stack.Screen name="CategoryList" component={CategoryListScreen} options={{ title: 'カテゴリ一覧' }} />
-        <Stack.Screen name="BoardList" component={BoardListScreen} options={{ title: '板一覧' }} />
+        <Stack.Screen
+          name="BoardList"
+          component={BoardListScreen}
+          options={{
+            title: '板一覧',
+            gestureEnabled: true, // スワイプジェスチャーを有効にする
+            gestureDirection: 'horizontal', // 左から右へのスワイプで戻る
+            cardStyleInterpolator: CardStyleInterpolators.forHorizontalIOS, // iOSスタイルの遷移アニメーション
+          }}
+        />
       </Stack.Navigator>
     </NavigationContainer>
   );

これもあっさりですね。gestureDirectionにhorizontalを指定するだけ。よくできているというか、これも誰でも設定するような項目なのでしょう。

Flutter版での動作のように画面上のどこでもフリックすればOKというわけではなく、画面の左端近くからフリックするというか、前の画面を引っ張り出すという動作になっています。GPT-4がコメントに書いてあるように、フリックというよりスワイプかと思います。もしかしたらFlutterでもこのような動作ができるのかもしれません。

そういえばいま気がついたのですが、前回の作業でできていませんでした。

  • 板一覧画面にもカテゴリ一覧画面と同じようなグリッド線を引いてください。
  • 現在のソースコードにマージしてください。
  • 板一覧画面とはグリッド線の引き方が違っています。GridItem.tsxを利用してください。
   return (
     <View style={styles.container}>
       <FlatList
         data={categoryContent}
-        renderItem={({ item }) => (
-          <View style={styles.item}>
-            <Text style={styles.itemText}>{item.board_name}</Text>
-          </View>
+        renderItem={({ item, index }) => (
+          <GridItem
+            name={item.board_name}
+            isFirstRow={index < 2} // 最初の2アイテムで最初の行
+            isLeftCell={index % 2 === 0} // 偶数インデックスが左側のセル
+            onPress={handlePress} // 実際には適切な処理を実装する
+          />
         )}
         keyExtractor={(_, index) => `board-${index}`}
         numColumns={2}

板一覧画面でグリッド線を引くために作ったGridItemが上手くそのまま利用できたようです。部品をそのまま再利用できるようにコーディングしてくれているのはありがたい!

カテゴリ一覧画面、板一覧画面と2画面完成です。残りはスレ一覧画面とレス一覧画面なので、画面数で言えば半分まできたということになります。実際にはレス内の画像表示、アンカー表示などがあるので工数としては1/3とか1/4になるのかもしれませんが。

それにしても今日の作業はさくさくと進みました。まったく引っかからず1時間程度でした。先のことを考えて再利用できるようにコンポーネント化しておくのは大事ですね。

ChatGPT頼みだとしても、オーダーする側も考えながら進めないといけないようです。前回React Nativeでトライしたときに失敗したのはこのあたりが原因かと思います。

ここまでのソースコードです。
https://github.com/yasuda0320/SurfPlank/tree/series004

続きはこちら。
https://zenn.dev/nori/articles/b8891fbf7a72fe

Flutter版はこちら。
https://zenn.dev/nori/articles/5444433481f549

Discussion