PUROGU LADESU

ポエムがメインのブログです。

【ReactNative】リストをスワイプさせる(1)

写真などをスワイプして次の画像を見れるようにします。
意外と簡単でScrollViewにpagingEnabledをつければ、スクリーンに表示されない部分はページめくりが有効になります。
ScrollViewの中身はViewやImageを並べておけばいいようです。

<ScrollView
  ref={imageScrollViewRef}
  horizontal
  pagingEnabled
  style={{
    height: Window.width,
  }}
>
  {item.image_uri?.map((v, i) => {
    return (
      <Image
        key={i.toString()}
        source={{ uri: item.image_uri?.[i] }}
        style={{
          height: Window.width,
          width: Window.width,
          resizeMode: 'contain',
        }}
      >
      </Image>
    );
  })}
</ScrollView>

ボタンとかをつけたら自分で制御が必要です。
画像の上にオーバーレイで進む、戻るボタンを付ける。

  <Image
   key={i.toString()}
    source={{ uri: item.image_uri?.[i] }}
    style={{
      height: Window.width,
      width: Window.width,
      resizeMode: 'contain',
    }}
  >
    <View
      key={i.toString()}
      style={{
        flex: 1,
        flexDirection: 'row',
        justifyContent:
          imageIndexShown == 0 ? 'flex-end' : 'space-between',
        alignItems: 'center',
        padding: 4,
      }}
    >
      <TouchableOpacity
        style={[
          styles.imageControlButton,
          {
            display: imageIndexShown == 0 ? 'none' : 'flex',
          },
        ]}
        onPress={() => {
          showNextImage(-1);
        }}
      >
        <Text style={styles.imageControlButtonText}>{'<'}</Text>
      </TouchableOpacity>
      <TouchableOpacity
        style={[
          styles.imageControlButton,
          {
            display:
              imageIndexShown == item.image_uri?.length - 1
                ? 'none'
                : 'flex',
          },
        ]}
        onPress={() => {
          showNextImage(1);
        }}
      >
        <Text style={styles.imageControlButtonText}>{'>'}</Text>
      </TouchableOpacity>
    </View>
  </Image>
imageControlButton: {
    backgroundColor: 'rgba(0,0,0,0.5)',
    width: 30,
    height: 30,
    borderRadius: 15,
    justifyContent: 'center',
    alignItems: 'center',
  },
  imageControlButtonText: { color: 'rgba(255,255,255,0.6)', fontWeight: '600' },

imageIndexShownで現在のページを保存します。 これ以外にスワイプしたときのページ変更の処理も必要です。 まるごとコンポーネント化したほうがいいですね。

  // ページを進む(direction=1)、戻る(direction=-1)
  const showNextImage = (direction) => {
    const nextIndex = imageIndexShown + direction;
    if (nextIndex > item.image_uri.length - 1) {
      return;
    }
    if (nextIndex < 0) {
      return;
    }

    imageScrollViewRef?.current?.scrollTo({
      x: Window.width * nextIndex,
      y: 0,
      animated: true,
    });

    setImageIndexShown(nextIndex);
  };