จำนวนการเปิดอ่าน 155
คะแนนเอกสาร

เตรียมเครื่องไม้เครื่องมือก่อน

  • IDE แจ่มๆ สักหนึ่งตัว ผมเลือกใช้ phpStorm เพราะดันมือลั่น ซื้อมาใช้แล้ว
  • node.js โหลดจาก https://nodejs.org/en/
  • มือถือ Android สเปคกลางๆ ไม่อ่อน ไม่แก่จนเกินไป

เริ่มต้นสร้าง Project

ติดตั้งตัวสร้าง app ของค่าย React กันก่อนครับ

npm install -g create-react-native-app

พอเสร็จแล้ว ก็สั่งก่อสร้างกันได้เลย

create-react-native-app app.track

จนมันเสร็จ ก็เข้าไปใน Project มันแล้วก็สั่งรัน

cd app.track

yarn start

ถ้าขึ้นประมาณนี้ ก็น่าจะโอเคแล้ว

ติดตั้ง App Expo ในมือถือเรา

เข้า Google Play ค้นหา App ชื่อ Expo เลยครับ แล้วติดตั้ง แค่นั้นล่ะ

เมื่อติดตั้่งเสร็จแล้ว ก็เปิด App ขึ้นมา กดปุ่ม Scan QR โค้ด จากนั้น ก็เอามาส่องใน terminal จากขั้นตอนข้างบน (มันบอกว่า ให้กด q เพื่อแสดง QR Code) ถ้าแสกนไม่ติด อย่างผมเนี่ย (เพราะไอ้ QR ดันเป็นสีเทา มันเลยสแกนไม่ติด) ก็กดพิมพ์ URL ไปตรงๆ เลยก็ได้ URL มันจะได้ประมาณนี้

exp://192.168.1.68:19000

พอเปิด URL แล้ว ตัว app จะทำการ build ให้รอสักแป๊บ พอได้เรียบร้อย ก็จะเป็นหน้า app เริ่มต้นของ react native โชว์ ขึ้นมาเลย

ซึ่งถ้าเราแก้ไฟล์ js ใน App ของเรา แล้ว save ตัวแอฟบนมือถือเราก็จะอัพเดท (แทบจะ) ทันทีเช่นเดียวกัน ซึ่งคงจะสะดวกมากเวลาพัฒนา App


ติดตั้ง Native Base

อันเนื่องจากเราสร้าง app ด้วยวิธี CRNA ดังนั้น ต้องติดตั้ง NativeBase ตามนี้ เริ่ม

npm install native-base --save
npm install @expo/vector-icons --save

แค่นั้น จากนั้นก็ สั่งยานแม่ได้เลย yarn start

ลองใช้ Native Base

ขี้เกียจอธิบาย เอาโค้ด Anatomy เต็มๆ ไปดูเลยแล้วกัน

import React from 'react';
import {Container, Header, Title, Content, Footer, FooterTab, Button, Left, Right, Body, Icon, Text} from 'native-base';

export default class App extends React.Component {
    constructor() {
        super();
        this.state = {
            isReady: false
        };
    }

    async componentWillMount() {
        await Expo.Font.loadAsync({
            'Roboto': require('native-base/Fonts/Roboto.ttf'),
            'Roboto_medium': require('native-base/Fonts/Roboto_medium.ttf'),
            Ionicons: require("@expo/vector-icons/fonts/Ionicons.ttf")
        });
        this.setState({isReady: true});
    }

    render() {
        if (!this.state.isReady) {
            return <Expo.AppLoading/>;
        }

        return (
            <Container>
                <Header>
                    <Left>
                        <Button transparent>
                            <Icon name='menu' style={{color: 'white'}}/>
                        </Button>
                    </Left>
                    <Body>
                    <Title>TEST App</Title>
                    </Body>
                    <Right/>
                </Header>
                <Content>
                    <Text>
                        This is Content Section
                    </Text>
                </Content>
                <Footer>
                    <FooterTab>
                        <Button full>
                            <Text>Footer</Text>
                        </Button>
                    </FooterTab>
                </Footer>
            </Container>
        );
    }
}

อันนี้ทดลองเอาโค้ด Anatomy Layout ของตัว NativeBase มาใส่ แล้วก็ แก้ๆ ปัญหาให้มันแสดงผลได้ นะครับ (อ่านหัวข้อถัดไปด้วยก็ดี) ซึ่งพอรันเสร็จ จะได้หน้าจอแบบนี้

เออโอเคนะ ง่ายดีด้วย


สรุปปัญหาที่เจอ

1. ไม่โหลด Font มา

เนื่องจากไอ้ตัว Nativebase มีการเรียกใช้ Font ประหลาดๆ ดังนั้นต้องเรียก Font มาก่อน แบบนี้

async componentWillMount() {
    await Expo.Font.loadAsync({
        'Roboto': require('native-base/Fonts/Roboto.ttf'),
        'Roboto_medium': require('native-base/Fonts/Roboto_medium.ttf'),
        'Ionicons': require("@expo/vector-icons/fonts/Ionicons.ttf")
    });
}

2. โหลด Font ยังไม่ทันเสร็จ ก็ render ก่อน

จากข้อข้างบน เนื่องจากมันโหลดมาแบบ async ดังนั้น บางทีมันยังไม่ทันโหลดเสร็จ หน้าจอดัน render ไปก่อน ก็ error แดงโร่กันไป ดังนั้น เราต้องเพิ่ม ของไปอีกสามส่วน เพื่อให้มันเสร็จสถานะว่าโหลดเสร็จแล้ว ค่อย render ส่วนอื่นเต็มๆ

เริ่มด้วยตั้ง state.isReady ใน constructor ก่อน

constructor() {
    super();
    this.state = {
        isReady: false
    };
}

เพิ่มตัว

async componentWillMount() {
    ...
    this.setState({isReady: true});
}

สุดท้าย ถ้ามันยังไม่ state.isReady ก็ให้มัน render หน้ารอ ไปก่อนแบบนี้

if (!this.state.isReady) {
    return <Expo.AppLoading/>;
}

3. ตัว App ไปอยู่ใต้ statusbar

แบบนี้

วิธีแก้ให้เติมสีลงใน Status Bar แบบนี้ (ประหลาดจนผมต้องยิ้มที่มุมปากหน่อยนึงเลยทีเดียวเชียว)

{
  "expo": {
    ...
    ...
    "androidStatusBarColor": "#000000",
    "androidStatusBar": {
      "barStyle": "light-content",
      "backgroundColor": "#334393"
    }
  }
}

จากนั้นก็ Reload ตัว Expo ใหม่ ด้วยการกดตรงนี้ ก็ใช้ได้เลย

ไอ้เมนูตรงนี้เรียกว่าอะไรหว่าลืม