wheatandcatの開発ブログ

React Nativeで開発しているペペロミア & memoirの技術系記事を投稿してます

React Nativeでチュートリアルを作成

memoirのチュートリアルを実装したので紹介

Pull Request

github.com

実装

ペペロミア作成時だと、react-native-app-intro-sliderを使用していましたが、今回はライブラリを使用せず実装しました。

github.com

実装は、以下の記事を参考に作成

medium.com

スライドは以下みたいな感じで実装できます。

import React, { memo, useState, useCallback, useRef } from 'react';
import {
  ScrollView,
  useWindowDimensions,
  StyleSheet,
  ViewStyle,
  NativeSyntheticEvent,
  NativeScrollEvent,
} from 'react-native';
import { StatusBar } from 'expo-status-bar';
import View from 'components/atoms/View';
import Text from 'components/atoms/Text';
import Button from 'components/atoms/Button';
import theme from 'config/theme';

type Props = {};

const Intro: React.FC<Props> = () => {
  const scrollViewRef = useRef<ScrollView>(null);
  const width = useWindowDimensions().width;
  const height = useWindowDimensions().height;
  const [page, setPage] = useState(0);

  const style: ViewStyle[] = [
    { width, height, justifyContent: 'center', alignItems: 'center' },
  ];

  const onScroll = useCallback(
    (event: NativeSyntheticEvent<NativeScrollEvent>) => {
      const { x } = event.nativeEvent.contentOffset;
      const nextPage = Math.floor(x / width);
      setPage(nextPage);
    },
    [width]
  );

  const onNext = useCallback(() => {
    const nextPage = page + 1;
    scrollViewRef?.current?.scrollTo?.({
      x: width * nextPage,
      y: 0,
      animated: true,
    });
    setPage(nextPage);
  }, [width, page]);

  return (
    <>
      <StatusBar backgroundColor={theme().color.primary.main} style="dark" />
      <View style={styles.wrap}>
        <ScrollView
          style={styles.wrap}
          horizontal={true}
          scrollEventThrottle={16}
          pagingEnabled={true}
          showsHorizontalScrollIndicator={false}
          onScroll={onScroll}
          ref={scrollViewRef}
        >
          <View style={style}>
            <Text>1</Text>
            <Button title="次へ" onPress={onNext} width={150} />
          </View>
          <View style={style}>
            <Text>2</Text>
            <Button title="次へ" onPress={onNext} width={150} />
          </View>
          <View style={style}>
            <Text>3</Text>
            <Button title="次へ" onPress={onNext} width={150} />
          </View>
          <View style={style}>
            <Text>4</Text>
            <Button title="次へ" onPress={onNext} width={150} />
          </View>
          <View style={style}>
            <Text>5</Text>
            <Button title="次へ" onPress={onNext} width={150} />
          </View>
        </ScrollView>
      </View>
    </>
  );
};

const styles = StyleSheet.create({
  wrap: {
    flex: 1,
    position: 'relative',
    height: '100%',
  },
});

export default memo(Intro);

動作は以下の通り

www.youtube.com

ScrollViewにhorizontalpagingEnabledを設定すれば、それっぽい動作になります。

        <ScrollView
          style={styles.wrap}
          horizontal={true}
          scrollEventThrottle={16}
          pagingEnabled={true}
          showsHorizontalScrollIndicator={false}
          onScroll={onScroll}
          ref={scrollViewRef}
        >

これに諸々要素を追加して、以下のように仕上げました。(コードはPull Request参照)

www.youtube.com