電通国際情報サービス、オープンイノベーションラボの比嘉康雄です。
今回は、Expoの公式チュートリアルをやっていきたいと思います。
- プロジェクトの作成
- Download assets
- Install dependencies
- アプリの実行
- コードの編集
- テキストの文字色の変更
- イメージの表示
- ImageViewerコンポーネント
- Buttonコンポーネント
- PhotoButtonコンポーネント
- 画像の選択
- まとめ
- 仲間募集
プロジェクトの作成
StickerSmash
プロジェクトを作成しましょう。
npx create-expo-app StickerSmash && cd StickerSmash
Download assets
https://docs.expo.dev/static/images/tutorial/sticker-smash-assets.zip
をダウンロードしてから解凍し、StickerSmash/assetsに格納します。既存のファイルは置き換えてください。
Install dependencies
Webでも実行できるようにするために、必要なモジュールをインストールします。
npx expo install react-dom react-native-web @expo/webpack-config
アプリの実行
プロジェクトのディレクトリで、npx expo start
を実行します。
wを押すと、Webアプリを試すことができます。
次のように表示されました。
コードの編集
プロジェクトのディレクトリで、code .
を実行して、VS Codeを立ち上げます。
背景を#25292e
に変更しましょう。
const styles = StyleSheet.create({ container: { flex: 1, backgroundColor: "#25292e", alignItems: "center", justifyContent: "center", }, });
次のように表示されました。
テキストのデフォルトの文字色は黒なので、背景が黒っぽくなったことで、文字が見え辛くなってしまいました。
テキストの文字色の変更
Textタグのstyle属性で、文字の色を白に指定しましょう。
<Text style={{ color: "#fff" }}> Open up App.js to start working on your app! </Text>
次のように表示されました。
イメージの表示
イメージを表示しましょう。
Imageコンポーネントをインポートします。
import { StyleSheet, View, Image } from 'react-native';
次は、イメージパスの設定です。
const PlaceholderImage = require('./assets/images/background-image.png');
Imageタグを使う前に、スタイルシートの設定をしましょう。
const styles = StyleSheet.create({ container: { flex: 1, backgroundColor: "#25292e", alignItems: "center", }, imageContainer: { flex: 1, paddingTop: 58, }, image: { width: 320, height: 440, borderRadius: 18, }, });
準備ができたので、Imageコンポーネントを使ってみましょう。
<View style={styles.imageContainer}> <Image source={PlaceholderImage} style={styles.image} /> </View>
下記のように表示されました。
ImageViewerコンポーネント
先ほど作ったイメージ表示機能をコンポーネント化しましょう。
StickSmashディレクトリの中にcomponentsディレクトリを作成します。
.../StickerSmash$ mkdir components
VS CodeでImageViewer.js
を作成します。
code components/ImageViewer.js
下記のコードをImageViewer.js
に書き込みます。
import { StyleSheet, Image } from 'react-native'; export default function ImageViewer({ placeholderImageSource }) { return ( <Image source={placeholderImageSource} style={styles.image} /> ); } const styles = StyleSheet.create({ image: { width: 320, height: 440, borderRadius: 18, }, });
App.js
からImageViewer.js
を呼び出します。
import ImageViewer from './components/ImageViewer'; const PlaceholderImage = require('./assets/images/background-image.png'); export default function App() { return ( <View style={styles.container}> <View style={styles.imageContainer}> <ImageViewer placeholderImageSource={PlaceholderImage} /> </View> <StatusBar style="auto" /> </View> ); }
見た目はもちろん以前と一緒です。
Buttonコンポーネント
これからボタンを2つ作りますが、その前に、Buttonコンポーネントを作ってそれを利用することにしましょう。
VS CodeでButton.js
を作成します。
code components/Button.js
下記のコードをButton.js
に書き込みます。
import { StyleSheet, View, Pressable, Text } from 'react-native'; export default function Button({ label }) { return ( <View style={styles.buttonContainer}> <Pressable style={styles.button} onPress={() => alert('You pressed a button.')}> <Text style={styles.buttonLabel}>{label}</Text> </Pressable> </View> ); } const styles = StyleSheet.create({ buttonContainer: { width: 320, height: 68, marginHorizontal: 20, alignItems: 'center', justifyContent: 'center', padding: 3, }, button: { borderRadius: 10, width: '100%', height: '100%', alignItems: 'center', justifyContent: 'center', flexDirection: 'row', }, buttonLabel: { color: '#fff', fontSize: 16, }, });
App.js
からButton.js
を呼び出します。
import Button from './components/Button'; <View style={styles.footerContainer}> <Button label="Choose a photo" /> <Button label="Use this photo" /> </View> const styles = StyleSheet.create({ // Styles that are unchanged from previous step are hidden for brevity. footerContainer: { flex: 1 / 3, alignItems: 'center', }, });
下記のように表示されました。
PhotoButtonコンポーネント
写真アイコンが表示されるボタンを作りましょう。@expo/vector-icon
をインストールします。
npx expo install @expo/vector-icons
VS CodeでPhotoButton.js
を作成します。
code components/PhotoButton.js
下記のコードをPhotoButton.js
に書き込みます。
import { StyleSheet, View, Pressable, Text } from "react-native"; import FontAwesome from "@expo/vector-icons/FontAwesome"; export default function PhotoButton({ label }) { return ( <View style={styles.buttonContainer}> <Pressable style={styles.button} onPress={() => alert("You pressed a button.")} > <FontAwesome name="picture-o" size={18} color="#25292e" style={styles.buttonIcon} /> <Text style={[styles.buttonLabel, {}]}>{label}</Text> </Pressable> </View> ); } const styles = StyleSheet.create({ buttonContainer: { width: 320, height: 68, marginHorizontal: 20, alignItems: "center", justifyContent: "center", padding: 3, borderWidth: 4, borderColor: "#ffd33d", borderRadius: 18, }, button: { borderRadius: 10, width: "100%", height: "100%", alignItems: "center", justifyContent: "center", flexDirection: "row", backgroundColor: "#fff", }, buttonIcon: { paddingRight: 8, }, buttonLabel: { color: "#25292e", fontSize: 16, }, });
下記のように表示されました。
画像の選択
画像を選択する機能を実装しましょう。expo-image-picker
をインストールします。
npx expo install expo-image-picker
App.js
でpickImageAsync
ファンクションを実装しましょう。選択した画像は、result.assets[0].uri
に入っています。
import * as ImagePicker from 'expo-image-picker'; const pickImageAsync = async () => { const result = await ImagePicker.launchImageLibraryAsync({ allowsEditing: true, quality: 1, }); if (!result.canceled) { alert(result.assets[0].uri); } else { alert('You did not select any image.'); } };
PhotoButton
でボタンを押したときの動作が定義できるように、onPress
属性を追加しましょう。
export default function PhotoButton({ label, onPress }) { return ( <View style={styles.buttonContainer}> <Pressable style={styles.button} onPress={onPress} > <FontAwesome name="picture-o" size={18} color="#25292e" style={styles.buttonIcon} /> <Text style={styles.buttonLabel>{label}</Text> </Pressable> </View> ); }
App.js
でPhotoButton
が押されたときに、pickImageAsync
ファンクションを呼び出します。
<PhotoButton label="Choose a photo" onPress={pickImageAsync} />
ImageViewer
で選択した画像を表示できるように、selectedImage
属性を追加します。
export default function ImageViewer( { placeholderImageSource, selectedImage }) { const imageSource = selectedImage ? { uri: selectedImage } : placeholderImageSource; return <Image source={imageSource} style={styles.image} />; }
App.js
で、写真が選択されたら、ImageViewer
に表示します。
import { useState } from "react"; const PlaceholderImage = require("./assets/images/background-image.png"); export default function App() { const [selectedImage, setSelectedImage] = useState(null); const pickImageAsync = async () => { const result = await ImagePicker.launchImageLibraryAsync({ allowsEditing: true, quality: 1, }); if (!result.canceled) { setSelectedImage(result.assets[0].uri); } else { alert("You did not select any image."); } }; return ( <View style={styles.container}> <View style={styles.imageContainer}> <ImageViewer placeholderImageSource={PlaceholderImage} selectedImage={selectedImage} /> </View> <View style={styles.footerContainer}> <PhotoButton label="Choose a photo" onPress={pickImageAsync} /> <Button label="Use this photo" /> </View> <StatusBar style="auto" /> </View> ); }
下記のように表示されました。
切りが良いので、前編はここまでとします。
まとめ
Expoの公式チュートリアルは、難易度もちょうどいい感じで、実践的な力が身につくなと感じました。ただ、JavaScriptじゃなくTypeScriptにしてほしかったところです。
仲間募集
私たちは同じグループで共に働いていただける仲間を募集しています。
現在、以下のような職種を募集しています。