Skip to content

Instantly share code, notes, and snippets.

@Nkzn
Last active July 21, 2018 04:03
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Nkzn/4752be9c78717a14650d3750f6ac6a70 to your computer and use it in GitHub Desktop.
Save Nkzn/4752be9c78717a14650d3750f6ac6a70 to your computer and use it in GitHub Desktop.
上越TechMeetup#2でのデモ手順

とりあえず画面遷移ライブラリ入れとこう

$ yarn add react-navigation

src/MainScreen.js

import React from 'react';
import { StyleSheet, Text, View } from 'react-native';

export default class MainScreen extends React.Component {
  static navigationOptions = {
    title: 'CRNA Demo',
  };

  render() {
    return (
      <View style={styles.container}>
        <Text>Open up App.js to start working on your app!</Text>
        <Text>Changes you make will automatically reload.</Text>
        <Text>Shake your phone to open the developer menu.</Text>
      </View>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#fff',
    alignItems: 'center',
    justifyContent: 'center',
  },
});

src/RootNavigator.js

import React from "react";
import { createStackNavigator } from "react-navigation";

import MainScreen from "./MainScreen";

export default createStackNavigator({
  Main: MainScreen,
});

App.js

import React from 'react';
import Root from "./src/RootNavigator";

export default class App extends React.Component {
  render() {
    return (
      <Root />
    );
  }
}

QRコードスキャン用の画面作ろう

まずはガワだけ。

src/QRCodeModal.js

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

export default class QRCodeModal extends React.Component {
  static navigationOptions = props => ({
    title: 'バーコード読み込み',
    headerLeft: (
      <TouchableOpacity onPress={() => {props.navigation.goBack()}}>
        <Text style={{ fontWeight:'bold', fontSize: 16, marginHorizontal: 16 }}>キャンセル</Text>
      </TouchableOpacity>
    )
  });

  render() {
    return (
      <View style={styles.container}>
        <Text>カメラの使用許可をリクエスト中です...</Text>
      </View>
    );
  }
}

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

src/MainScreen.js

  import React from 'react';
- import { StyleSheet, Text, View } from 'react-native';
+ import { StyleSheet, Text, View, Button } from 'react-native';

  export default class MainScreen extends React.Component {
    static navigationOptions = {
      title: 'CRNA Demo',
    };

    render() {
      return (
        <View style={styles.container}>
          <Text>Open up App.js to start working on your app!</Text>
          <Text>Changes you make will automatically reload.</Text>
          <Text>Shake your phone to open the developer menu.</Text>
+         <View style={{ height: 16 }} />
+         <Button
+           title="QRCode Sample"
+           onPress={() => this.props.navigation.navigate('QRCode')} />
        </View>
      );
    }
  }

  const styles = StyleSheet.create({
    container: {
      flex: 1,
      backgroundColor: '#fff',
      alignItems: 'center',
      justifyContent: 'center',
    },
  });

src/RootNavigator.js

  import React from "react";
  import { createStackNavigator } from "react-navigation";

  import MainScreen from "./MainScreen";
+ import QRCodeModal from "./QRCodeModal";

  export default createStackNavigator({
    Main: MainScreen,
+   QRCode: QRCodeModal,
+ }, {
+   mode: "modal",
  });

QRコードをスキャンしよう

$ yarn add lodash

src/QRCodeModal.js

  import React from "react";
+ import { BarCodeScanner, Permissions } from "expo";
- import { View, Text, TouchableOpacity, StyleSheet } from "react-native";
+ import { View, Text, TouchableOpacity, StyleSheet, ScrollView, Dimensions } from "react-native";
+ import { throttle } from "lodash";

+ const screen = Dimensions.get("window");

  export default class QRCodeModal extends React.Component {
    static navigationOptions = props => ({
      title: 'バーコード読み込み',
      headerLeft: (
        <TouchableOpacity onPress={() => {props.navigation.goBack()}}>
          <Text style={{ fontWeight:'bold', fontSize: 16, marginHorizontal: 16 }}>キャンセル</Text>
        </TouchableOpacity>
      )
    });

+   constructor(props: any) {
+     super(props);
+
+     this.state = {
+       hasCameraPermission: null,
+       lastReadCode: {
+         type: null,
+         data: null,
+       }
+     }
+   }
+
+   async componentDidMount() {
+     const { status } = await Permissions.askAsync(Permissions.CAMERA);
+     this.setState({
+       hasCameraPermission: status === 'granted',
+     });
+   }
+
+   handleBarCodeRead = throttle((data) => this._handleBarCodeRead(data), 1000);
+
+   _handleBarCodeRead(data) {
+     console.log("_handleBarCodeRead", data);
+     if (data.type === "org.iso.QRCode") {
+       if (!data) {
+           return;
+       }
+
+       this.setState({
+         lastReadCode: {
+           type: data.type,
+           data: data.data,
+         }
+       });
+     }
+   }
+
    render() {
+     const { hasCameraPermission, lastReadCode } = this.state;
+
+     if (hasCameraPermission === true) {
+       return (
+         <View style={styles.container}>
+           <BarCodeScanner
+             onBarCodeRead={data => this.handleBarCodeRead(data)}
+             style={{ width: screen.width, height: screen.height }}
+           />
+           <View style={{
+             position: "absolute",
+             bottom: 0,
+             width: screen.width,
+             height: (screen.width)/3,
+             backgroundColor: "rgba(0, 0, 0, 0.5)"
+           }}>
+             <Text style={{ color: "white" }}>
+               type: {lastReadCode.type}
+             </Text>
+             <Text style={{ color: "white" }}>
+               data: {lastReadCode.data}
+             </Text>
+           </View>
+         </View>
+       );
+     }
+
+     if (hasCameraPermission === false) {
+       return (
+         <View style={styles.container}>
+           <Text>
+             <Text>カメラの使用許可が得られませんでした。</Text>
+             <Text>iOSの設定から許可してください。</Text>
+           </Text>
+         </View>
+       );
+     }
+
      return (
        <View style={styles.container}>
          <Text>カメラの使用許可をリクエスト中です...</Text>
        </View>
      );
    }
  }

  const styles = StyleSheet.create({
    container: {
      flex: 1,
      alignItems: "center",
      justifyContent: "center",
    }
  });
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment