全棧工程師之路-React Native之掃描二維碼

前言

之前開發移動端頁面,總會被原生開發各類嫌棄,H5性能過低,動畫不流暢,身爲一名小前端我能怎麼辦呢?老是在無人的夜裏,內心默默地流淚~前端

後來 React Native 出來之後,終於能夠翻身農奴把歌唱:哈哈哈,原生的小X人們,等待我 RN 的小皮鞭吧,pia~react

可是那時候如果不懂點 Android 或者 iOS,徹底用 RN 開發一個 App,是很是痛苦的。web

在嘗試一段時間之後,因爲實在難以忍受調教各類莫明其妙的報錯,讓我一度對這項新技能又愛又恨,望而生畏~react-native

可是最近因爲項目上的需求又撿了起來,猛然發現,原來不知不覺間,RN 這迷人的小妖精已經成長得愈加成熟了~antd

好了廢話很少說,把口水擦乾淨後,咱們先來說講本次主題:如何破解一張有碼的圖片~async

項目構建

準備

如何讀懂這張有碼的圖片就是咱們要攻克的最大難題了,可是若是單憑我自身大腦的人工智能,我想這問題是無解了。函數

沒錯,咱們須要用到照相機,隨手一搜react-native-camera。。。工具

咦我是亂搜的,還真有這個庫啊。。。再搭配react-native-qrcode-scanner,嗯,就是你了,和我一塊兒拯救銀河系吧~性能

開始工做

首先項目根目錄安裝三方庫,經過yarn add命令安裝相應包文件學習

因爲會用到 native 的功能,react link會自動向 native 模塊中添加各類依賴和導包的操做。

$ yarn add react-native-camera
$ react-native link react-native-camera
$ yarn add react-native-qrcode-scanner
$ react-native link react-native-qrcode-scanner
複製代碼

這裏咱們假設點擊一個小按鈕,而後進入相冊,掃描出這張有碼的二維圖後,回到小按鈕頁面,並彈出掃描內容。

須要注意的一點是:按鈕頁和相冊掃描是兩個頁面,這裏咱們用react-navigation管理路由,具體使用詳見這裏

先看看App.js:

import React from 'react';
import { StackNavigator } from 'react-navigation';
import Home from './Home';
import Scanner from './Scanner';

// Home 和 Scanner 是兩個頁面,點開應用後首先進入 Home
const Stack = StackNavigator({
  Home: {
    screen: Home,
  },
  Scanner: {
    screen: Scanner,
  },
});

export default Stack;
複製代碼

這裏的Home,react-navigation自動會往props上加個navigation屬性,相似 web 開發時的 history,有 push, pop,replace等多個方法。

Home.js只須要一個按鈕,點擊跳轉至 Scanner 頁便可

import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { Button, Toast } from 'antd-mobile';

export default class Home extends Component {

  // react-navigation 的 StackNavigator 會自動在添加組件的 props 上添加 navigation 屬性
  static propTypes = {
    navigation: PropTypes.object.isRequired,
  };

  // 點擊按鈕時觸發
  scan = () => {
    this.props.navigation.navigate('Scanner', {
      onRead: this.onRead
    });
  };

  // 傳遞給下一個頁面的回調函數,顯示傳入內容
  onRead = (message) => {
    Toast.success(message);
  };

  render() {
    return (
      <Button onClick={this.scan} >屠龍寶刀,點擊就送</Button>
    );
  }
}
複製代碼

Scanner.js 就是本次的重點了

import React, { Component } from 'react';
import QRCodeScanner from 'react-native-qrcode-scanner';

const Scanner = props => {
  const { state, goBack } = props.navigation;

  // onRead 是相機掃描二維碼後自動調用,首先返回上一頁,而後再調用傳入的回調函數,顯示掃描內容
  return (
    <QRCodeScanner onRead={e => { goBack(); state.params.onRead(e.data); }} /> ); } export Scanner; 複製代碼

至此,全部的工做結束。

探索

依然很麻煩不是麼?畢竟須要引入兩個三方包呢,將來 RN 升級會不會不兼容?

因此即便已給了我莫大的好處,我正義凜然的心裏依然是拒絕的。

等等,大俠您等一等!!!先把我脖子上的刀放下來好好說,我不是故意逗你玩的。

不行,我陳D秀此次必定要站着把話說完!

這裏不得不說下Expo,一款 RN 開發的工具鏈,集成並提供了 RN 開發過程當中各類問題的解決方案,也是官網目前推薦方式。

因而第二個文件 Scanner.js 修改一下:

import React, { Component } from 'react';
import { BarCodeScanner, Permissions } from 'expo';

class Scanner extends Component {
  state = {
    hasCameraPermission: null,
  };

  static propTypes = {
    navigation: PropTypes.object.isRequired,
  };

  // 這裏首先斷定是否擁有相機權限,有咱們才能正大光明的調用
  async componentWillMount() {
    const { status } = await Permissions.askAsync(Permissions.CAMERA);
    this.setState({ hasCameraPermission: status === 'granted' });
  }

  // 掃描成功自動調用,這裏先返回上一頁,再調用回調函數,顯示掃描內容
  handleBarCodeRead = ({ data }) => {
    const { goBack, state } = this.props.navigation;
    goBack();
    state.params.onRead(data);
  };

  render() {
    const { hasCameraPermission } = this.state;

    // 若無權限,提示用戶
    if (hasCameraPermission === null) {
      return <Text>Requesting for camera permission</Text>;
    } else if (hasCameraPermission === false) {
      return <Text>No access to camera</Text>;
    }

    return (
      <View style={{ flex: 1 }}> <BarCodeScanner onBarCodeRead={this.handleBarCodeRead} style={StyleSheet.absoluteFill} /> </View> ); } } export default Scanner; 複製代碼

好了,圓滿了。對於這智慧的結晶,我仍是比較滿意的,謝謝你們讚許的目光。

總結

如今使用 RN 最大的感覺是,各類開發裝備愈加全面,固然也或許是以前並未深刻學習,對這塊的技術鏈瞭解太少。

整個開發體驗提高不止一個檔次,讓我再次燃起了心裏征服的慾望。

哈哈哈,原生的小X人們,等待着我 RN 的小皮鞭吧,pia


相關文章
相關標籤/搜索