Expo.ioMaterial DesignReactReact Native React Native PaperReact Navigation

[ReactNative/Expo] Paper と Navigation v5 で Twitter Clone アプリを作成する〜初心者向け〜

scarf-4849441_1920 Expo.io
スポンサーリンク
スポンサーリンク

Drawer 作成

twitter-clone-example アプリでは Drawer をすべてのスクリーンで閲覧出来るようにしますので、Drawer が ルートナビゲータ となります。

Main.js に Drawer 設定を追加するため、Main.js を下記のように変更します。

  • VSCode で rnfcomp ( 使用方法 ) と打ち込んで DrawerContentHomeScreen を作成します。( コピぺ可能 ▼ )

src/Main.js

// Main.js

import React from "react";
import { Text, View } from "react-native";
import { createDrawerNavigator } from "@react-navigation/drawer";

const Drawer = createDrawerNavigator();

function DrawerContent() {
  return (
    <View style={{ flex: 1, alignItems: "center", justifyContent: "center" }}>
      <Text>Drawer content</Text>
    </View>
  );
}

function HomeScreen() {
  return (
    <View style={{ flex: 1, alignItems: "center", justifyContent: "center" }}>
      <Text>Home Screen</Text>
    </View>
  );
}

export const Main = () => {
  return (
    <Drawer.Navigator drawerContent={() => <DrawerContent />}>
      <Drawer.Screen name="Home" component={HomeScreen} />
    </Drawer.Navigator>
  );
};

iOS シミュレータを再起動 ( ⌘ R ) して確認すると、▼ のように動作します。

最終的に Main.js にはテーマや RTL の切替の設定が入るので、DrawerContent と HomeScreen を含む Stack ナビケーターを別のファイルに分離します。

必要なファイルを作成します。▼

try🐶everything twitter-clone-example$ touch ./src/RootNavigator.js
try🐶everything twitter-clone-example$ touch ./src/DrawerContent.js
try🐶everything twitter-clone-example$ touch ./src/StackNavigator.js

StackNavigatorDrawerContentRootNavigator にインポートして設定します。
NavigationContainerApp.js で設定しているのでここでは設定しません

スポンサーリンク

src/RootNavigator.js ファイルを作成します。( VSCodeで imrnfc 実行 )

// RootNavigator.js
import React from "react";
import { createDrawerNavigator } from "@react-navigation/drawer";

import { StackNavigator } from "./StackNavigator";
import { DrawerContent } from "./DrawerContent";

const Drawer = createDrawerNavigator();

export const RootNavigator = () => {
  return (
    <Drawer.Navigator drawerContent={props => <DrawerContent {...props} />}>
      <Drawer.Screen name="Home" component={StackNavigator} />
    </Drawer.Navigator>
  );
};

src/DrawerContent.js ファイルを作成します。

// DrawerContent
import React from "react";
import { View, Text, StyleSheet } from "react-native";

export const DrawerContent = props => {
  return (
    <View style={styles.container}>
      <Text>DrawerContent</Text>
    </View>
  );
};

const styles = StyleSheet.create({
  container: {
    flex: 1,
    alignItems: "center",
    justifyContent: "center"
  }
});
スポンサーリンク

src/StackNavigator.js ファイルを作成します。

// StackNavigator.js
import React from "react";
import { View, Text, StyleSheet } from "react-native";

export const StackNavigator = props => {
  return (
    <View style={styles.container}>
      <Text>StackNavigator</Text>
    </View>
  );
};

const styles = StyleSheet.create({
  container: {
    flex: 1,
    alignItems: "center",
    justifyContent: "center"
  }
});

src/Main.js ファイルを変更します。

// Main.js
import React from "react";
import { Provider as PaperProvider } from "react-native-paper";
import { RootNavigator } from "./RootNavigator";

export const Main = () => {
  return (
    <PaperProvider>
      <RootNavigator />
    </PaperProvider>
  );
};

iOS シミュレータを確認します。▼ のように動作すれば OK です。

次は、DrawerContentStackNavigator の詳細を設定します。

現時点では何もない状態なので、DrawerContentScrollViewDrawerItem そして、AvatarTextSwitch などを使用して設定します。

スポンサーリンク

src/DrawerContent.js

下記のようにファイルを作成します。( コピぺ可能 ▼ )

// DrawerContent.js
import React from "react";
import { View, StyleSheet } from "react-native";
import { DrawerItem, DrawerContentScrollView } from "@react-navigation/drawer";
import {
  Avatar,
  Title,
  Caption,
  Paragraph,
  Drawer,
  Text,
  TouchableRipple,
  Switch
} from "react-native-paper";
import { MaterialCommunityIcons } from "@expo/vector-icons";

export function DrawerContent(props) {
  return (
    <DrawerContentScrollView {...props}>
      <View style={styles.drawerContent}>
        <View style={styles.userInfoSection}>
          <Avatar.Image
            source={{
              uri:
                "https://pbs.twimg.com/profile_images/952545910990495744/b59hSXUd_400x400.jpg"
            }}
            size={50}
          />
          <Title style={styles.title}>Dawid Urbaniak</Title>
          <Caption style={styles.caption}>@trensik</Caption>
          <View style={styles.row}>
            <View style={styles.section}>
              <Paragraph style={[styles.paragraph, styles.caption]}>
                202
              </Paragraph>
              <Caption style={styles.caption}>Following</Caption>
            </View>
            <View style={styles.section}>
              <Paragraph style={[styles.paragraph, styles.caption]}>
                159
              </Paragraph>
              <Caption style={styles.caption}>Followers</Caption>
            </View>
          </View>
        </View>
        <Drawer.Section style={styles.drawerSection}>
          <DrawerItem
            icon={({ color, size }) => (
              <MaterialCommunityIcons
                name="account-outline"
                color={color}
                size={size}
              />
            )}
            label="Profile"
            onPress={() => {}}
          />
          <DrawerItem
            icon={({ color, size }) => (
              <MaterialCommunityIcons name="tune" color={color} size={size} />
            )}
            label="Preferences"
            onPress={() => {}}
          />
          <DrawerItem
            icon={({ color, size }) => (
              <MaterialCommunityIcons
                name="bookmark-outline"
                color={color}
                size={size}
              />
            )}
            label="Bookmarks"
            onPress={() => {}}
          />
        </Drawer.Section>
        <Drawer.Section title="Preferences">
          <TouchableRipple onPress={() => {}}>
            <View style={styles.preference}>
              <Text>Dark Theme</Text>
              <View pointerEvents="none">
                <Switch value={false} />
              </View>
            </View>
          </TouchableRipple>
          <TouchableRipple onPress={() => {}}>
            <View style={styles.preference}>
              <Text>RTL</Text>
              <View pointerEvents="none">
                <Switch value={false} />
              </View>
            </View>
          </TouchableRipple>
        </Drawer.Section>
      </View>
    </DrawerContentScrollView>
  );
}

const styles = StyleSheet.create({
  drawerContent: {
    flex: 1
  },
  userInfoSection: {
    paddingLeft: 20
  },
  title: {
    marginTop: 20,
    fontWeight: "bold"
  },
  caption: {
    fontSize: 14,
    lineHeight: 14
  },
  row: {
    marginTop: 20,
    flexDirection: "row",
    alignItems: "center"
  },
  section: {
    flexDirection: "row",
    alignItems: "center",
    marginRight: 15
  },
  paragraph: {
    fontWeight: "bold",
    marginRight: 3
  },
  drawerSection: {
    marginTop: 15
  },
  preference: {
    flexDirection: "row",
    justifyContent: "space-between",
    paddingVertical: 12,
    paddingHorizontal: 16
  }
});

ここまで、問題なければ下記のように動作します。

次は、Stack Navigator を設定しましょう。


お名前.com

https://www.xserver.ne.jp/lp/service01/

コメント

  1. ふぁびょん より:

    参考になりました。ありがとうございます。
    React NativeはネイティブアプリらしいUIが作りづらく苦労していたので参考になりました。
    技術革新も早くコピペしてもまともに動かないサイトも多く非常に参考になりました。

    動かない部分もありますが自分で調べてみようと思います。

タイトルとURLをコピーしました