見出し画像

React Native Paper の使い方

「React Native Paper」の使い方をまとめました。


前回

1. React Native Paper

React Native Paper」は、「React Native」のUIライブラリのひとつです。デフォルトでGoogleのマテリアルデザインガイドラインに準拠します。

2. React Native Paper の使い方

「React Native Paper」の使い方は次のとおりです。

2-1. セットアップ

(1) React Nativeプロジェクトの生成。

npx react-native init my_app
cd my_app

(2) パッケージのインストール。

npm install react-native-paper react-native-safe-area-context react-native-vector-icons 
npm install @react-native-community/masked-view

2-2. Androidのセットアップ

(1) android/app/build.gradle(NOT android/build.gradle)に以下の設定を追加。

apply from: file("../../node_modules/react-native-vector-icons/fonts.gradle")

2-3. iOSのセットアップ

(1) podのインストール。

cd ios
pod install
cd ..

(2) workspaceを開き、署名し、iPhoneにインストールできることを確認。

(3) 「Info.plist」に以下の項目を追加。

<key>UIAppFonts</key>
<array>
  <string>AntDesign.ttf</string>
  <string>Entypo.ttf</string>
  <string>EvilIcons.ttf</string>
  <string>Feather.ttf</string>
  <string>FontAwesome.ttf</string>
  <string>FontAwesome5_Brands.ttf</string>
  <string>FontAwesome5_Regular.ttf</string>
  <string>FontAwesome5_Solid.ttf</string>
  <string>FontAwesome6_Brands.ttf</string>
  <string>FontAwesome6_Regular.ttf</string>
  <string>FontAwesome6_Solid.ttf</string>
  <string>Foundation.ttf</string>
  <string>Ionicons.ttf</string>
  <string>MaterialIcons.ttf</string>
  <string>MaterialCommunityIcons.ttf</string>
  <string>SimpleLineIcons.ttf</string>
  <string>Octicons.ttf</string>
  <string>Zocial.ttf</string>
  <string>Fontisto.ttf</string>
</array>

2-4. React Native Paper の使い方

(1) PaperProviderの追加。
PaperProvider」でルートコンポーネントをラップします。

・index.js

import { AppRegistry } from 'react-native';
import { name as appName } from './app.json';
import { Provider as PaperProvider } from 'react-native-paper';
import App from './App';

// ホームスクリーン
const Main = () => (
  <PaperProvider>
    <App />
  </PaperProvider>
);

AppRegistry.registerComponent(appName, () => Main);

(2) コードの編集。

・App.tsx

import * as React from 'react';
import { Button, Text } from 'react-native-paper';
import { SafeAreaView } from 'react-native';

// アプリ
const App: React.FC = () => (
  <SafeAreaView style={{flex: 1, justifyContent: 'center', alignItems: 'center'}}>
    <Text style={{fontSize: 24, marginBottom: 20}}>Hello!</Text>
    <Button icon="camera" mode="contained" onPress={() => console.log('Pressed')}>
      Press me
    </Button>
  </SafeAreaView>
);

export default App;

(3) コードの実行。

npm start

3. テーマのカスタマイズ

(1) カスタムテーマを定義し、PaperProviderのthemeに設定。

import { AppRegistry } from 'react-native';
import { name as appName } from './app.json';
import { MD3DarkTheme, Provider as PaperProvider } from 'react-native-paper';
import App from './App';

// カスタムテーマの作成
const customDarkTheme = {
  ...MD3DarkTheme,
  colors: {
    ...MD3DarkTheme.colors,
    primary: '#ffffff', // プライマリカラー
    background: '#000000', // 背景色
    surface: '#000000', // サーフェイスの色
    onSurface: '#ffffff', // サーフェイス上のテキスト・アイコンの色
  },
};

// ホームスクリーン
const Main = () => (
  <PaperProvider theme={customDarkTheme}>
    <App />
  </PaperProvider>
);

AppRegistry.registerComponent(appName, () => Main);

カスタムテーマは、「DefaultTheme」「MD3LightTheme」「MD3DarkTheme」をベースに作成します。

(2) React Nativeのコンポーネントのstyleにthemeを直接設定。
「React Native Paper」のコンポーネントには直接反映されますが、「React Native」のコンポーネント (SafeAreaViewなど) には直接反映されないため、styleを指定する必要があります。

import * as React from 'react';
import { Button, Text, useTheme } from 'react-native-paper';
import { SafeAreaView } from 'react-native';

// アプリ
const App: React.FC = () => {
  // テーマの取得
  const theme = useTheme();

  // UI
  return (
    <SafeAreaView style={{flex: 1, justifyContent: 'center', alignItems: 'center', backgroundColor: theme.colors.background}}>
      <Text style={{fontSize: 24, marginBottom: 20}}>Hello!</Text>
      <Button icon="camera" mode="contained" onPress={() => console.log('Pressed')}>
        Press me
      </Button>
    </SafeAreaView>
  );
}

export default App;

4. コンポーネント一覧

react-native-paper」のコンポーネント一覧は、以下で確認できます。

ActivityIndicator
Appbar
Avatar
Badge
Banner
BottomNavigation
Button
Card
Checkbox
Chip
DataTable
Dialog
Divider
Drawer
FAB
HelperText
Icon
IconButton
List
Menu
Modal
Portal
ProgressBar
RadioButton
Searchbar
SegmentedButtons
Snackbar
Surface
Switch
Text
TextInput
ToggleButton
Tooltip
TouchableRipple

4-1. Text

import * as React from 'react';
import { Text } from 'react-native-paper';
import { SafeAreaView } from 'react-native';

// アプリ
const App: React.FC = () => {
  // UI
  return (
    <SafeAreaView style={{flex: 1, justifyContent: 'center', alignItems: 'center'}}>
      <Text variant="displayLarge">Display Large</Text>
      <Text variant="displayMedium">Display Medium</Text>
      <Text variant="displaySmall">Display small</Text>

      <Text variant="headlineLarge">Headline Large</Text>
      <Text variant="headlineMedium">Headline Medium</Text>
      <Text variant="headlineSmall">Headline Small</Text>

      <Text variant="titleLarge">Title Large</Text>
      <Text variant="titleMedium">Title Medium</Text>
      <Text variant="titleSmall">Title Small</Text>

      <Text variant="bodyLarge">Body Large</Text>
      <Text variant="bodyMedium">Body Medium</Text>
      <Text variant="bodySmall">Body Small</Text>

      <Text variant="labelLarge">Label Large</Text>
      <Text variant="labelMedium">Label Medium</Text>
      <Text variant="labelSmall">Label Small</Text>
    </SafeAreaView>
  );
}

export default App;

4-2. Button

import * as React from 'react';
import { Button } from 'react-native-paper';
import { SafeAreaView } from 'react-native';

// アプリ
const App: React.FC = () => {
  // UI
  return (
    <SafeAreaView style={{flex: 1, justifyContent: 'center', alignItems: 'center'}}>
      <Button icon="camera" mode="contained" onPress={() => console.log('Pressed')}>
        Press me
      </Button>
    </SafeAreaView>
  );
}

export default App;

4-3. TextInput

import React from 'react';
import { TextInput } from 'react-native-paper';
import { SafeAreaView } from 'react-native';

// アプリ
const App = () => {
  const [text, setText] = React.useState("");
  
  // UI
  return (
    <SafeAreaView style={{ flex: 1 }}>
      <TextInput
        label="Email"
        value={text}
        onChangeText={text => setText(text)}
      />
    </SafeAreaView>
  );
};

export default App;

4-4. Dialog

import * as React from 'react';
import { Portal, Text, Button, Dialog } from 'react-native-paper';
import { View, SafeAreaView } from 'react-native';

// アプリ
const App: React.FC = () => {
  const [visible, setVisible] = React.useState(false);

  // ダイアログの表示
  const showDialog = () => setVisible(true);

  // ダイアログの非表示
  const hideDialog = () => setVisible(false);

  // UI
  return (
    <SafeAreaView style={{flex: 1, justifyContent: 'center', alignItems: 'center'}}>
      <View>
        <Button mode="contained" onPress={showDialog}>Show Dialog</Button>

        <Portal>
          <Dialog visible={visible} onDismiss={hideDialog}>
            <Dialog.Title>Alert</Dialog.Title>
            <Dialog.Content>
              <Text variant="bodyMedium">This is simple dialog</Text>
            </Dialog.Content>
            <Dialog.Actions>
              <Button onPress={hideDialog}>Done</Button>
            </Dialog.Actions>
          </Dialog>
        </Portal>
      </View>
    </SafeAreaView>
  );
}

export default App;

4-5. ActivityIndicator

import React from 'react';
import { ActivityIndicator, MD2Colors } from 'react-native-paper';
import { SafeAreaView } from 'react-native';

// アプリ
const App = () => {
  // UI
  return (
    <SafeAreaView style={{ flex: 1 }}>
      <ActivityIndicator animating={true} color={MD2Colors.red800} />
    </SafeAreaView>
  );
};

export default App;

4-6. CheckBox

import * as React from 'react';
import { Checkbox } from 'react-native-paper';
import { SafeAreaView } from 'react-native';

// アプリ
const App: React.FC = () => {
  const [checked, setChecked] = React.useState(false);
  
  // UI
  return (
    <SafeAreaView style={{ flex: 1 }}>
      <Checkbox
        status={checked ? 'checked' : 'unchecked'}
        onPress={() => {
          setChecked(!checked);
        }}
      />
    </SafeAreaView>
  );
}

export default App;

4-7. RadioButton

import React from 'react';
import { RadioButton } from 'react-native-paper';
import { SafeAreaView } from 'react-native';

// アプリ
const App = () => {
  const [checked, setChecked] = React.useState('first');

  // UI
  return (
    <SafeAreaView style={{flex: 1}}>
      <RadioButton
        value="first"
        status={ checked === 'first' ? 'checked' : 'unchecked' }
        onPress={() => setChecked('first')}
      />
      <RadioButton
        value="second"
        status={ checked === 'second' ? 'checked' : 'unchecked' }
        onPress={() => setChecked('second')}
      />
    </SafeAreaView>
  );
};

export default App;

4-8. TouchableRipple

import React from 'react';
import { TouchableRipple, Text } from 'react-native-paper';
import { SafeAreaView } from 'react-native';

// アプリ
const App = () => {
  // UI
  return (
    <SafeAreaView style={{ flex: 1 }}>
      <TouchableRipple
        style={{ flex: 1 }}
        onPress={() => console.log('Pressed')}
        rippleColor="rgba(0, 0, 0, .32)"
      >
        <Text>Press anywhere</Text>
      </TouchableRipple>
    </SafeAreaView>
  );
};

export default App;

【おまけ】 Androidのリリースビルド

(1) release.keystoreの作成。
「android/app/release.keystore」に生成されます。本番では安全なパスワードを指定してください。

keytool -genkey -v -keystore android/app/release.keystore -keyalg RSA -keysize 2048 -validity 10000 -alias androidreleasekey
キーストアのパスワードを入力してください:  android
新規パスワードを再入力してください: android
姓名は何ですか。
  [Unknown]:  Taro
組織単位名は何ですか。
  [Unknown]:  Development
組織名は何ですか。
  [Unknown]:  Taro
都市名または地域名は何ですか。
  [Unknown]:  Tokyo
都道府県名または州名は何ですか。
  [Unknown]:  Tokyo
この単位に該当する2文字の国コードは何ですか。
  [Unknown]:  JP
CN=npaka, OU=Development, O=npaka, L=Tokyo, ST=Tokyo, C=JPでよろしいですか。
  [いいえ]:  Y

(2) 「android/app/build.gradle」の編集。

・defaultConfig の基本設定を確認

    defaultConfig {
        applicationId "com.my_app"
        minSdkVersion rootProject.ext.minSdkVersion
        targetSdkVersion rootProject.ext.targetSdkVersion
        versionCode 1
        versionName "1.0"
    }

・signingConfigs にリリース用の設定を追加

    signingConfigs {
        release {
            storeFile file('release.keystore')
            storePassword 'android'
            keyAlias 'androidreleasekey'
            keyPassword 'android'
        } 

・buildTypes にリリース用の設定を追加

    buildTypes {
        release {
            signingConfig signingConfigs.release
            minifyEnabled enableProguardInReleaseBuilds
            proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro"
        }

(3) ビルド。
「android/app/build/outputs/apk/release/」にリリースビルド(app-release.apk)が生成されます。

cd android
./gradlew assembleRelease
cd ..

(4) リリースビルド(app-release.apk)をAndroid端末にインストール。
Android端末とPCをUSB接続し、以下のコマンドを実行します。

adb install app-release.apk

次回



この記事が気に入ったらサポートをしてみませんか?