Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> ระบบ >> Android

สร้างแอปข่าว Android ที่แข็งแกร่งด้วย React Native และ Native Base

เราอยู่ในโลกที่เปลี่ยนแปลงตลอดเวลา หากคุณต้องการติดตามข่าวสารให้ทันเหตุการณ์ แอปข่าวที่ดีจึงเป็นสิ่งจำเป็น

ในบทความนี้ เราจะสร้างแอปพลิเคชันข่าวสำหรับ Android โดยใช้ React Native เพื่อช่วยให้คุณเรียนรู้เทคโนโลยีที่น่าสนใจและอยู่ในข่าวเสมอ แอปนี้จะดึงหัวข้อข่าวจากแหล่งข่าวต่างๆ และแสดงตามหมวดหมู่

สร้างแอปข่าว Android ที่แข็งแกร่งด้วย React Native และ Native Base

นี่คือรูปแบบของแอปเมื่อเสร็จสมบูรณ์ มาเริ่มกันเลย

วิธีติดตั้ง Expo

Expo คืออะไร? Expo เป็นเฟรมเวิร์กที่ช่วยให้คุณสร้างและปรับใช้แอป React Native ได้อย่างรวดเร็วและง่ายดาย

มาติดตั้งกัน

npm install --global expo-cli
การติดตั้ง Expo

รันคำสั่งนี้ในเทอร์มินัลเพื่อติดตั้ง Expo CLI โดยใช้ --global เพื่อให้ติดตั้งทั่วระบบ

หลังจากติดตั้งเสร็จ เราต้องสร้างโปรเจกต์ Expo

expo init News-Application
การสร้างโปรเจกต์ Expo

ใช้คำสั่งด้านบนเพื่อเริ่มต้นโปรเจกต์ ระบบจะถามรายละเอียด เช่น ชื่อแอป การใช้ TypeScript หรือเริ่มจากโปรเจกต์ว่าง ให้เลือก blank แล้วกด Enter

ระบบจะดาวน์โหลดแพ็กเกจและ dependencies ทั้งหมด เมื่อเสร็จแล้ว ให้เข้าโฟลเดอร์โปรเจกต์ และพิมพ์ expo start เพื่อเปิดเครื่องมือนักพัฒนาในเบราว์เซอร์

สร้างแอปข่าว Android ที่แข็งแกร่งด้วย React Native และ Native Base
Expo developer tools

ด้านซ้ายจะมีตัวเลือก เช่น รันบนอุปกรณ์ Android/Emulator หรือ iOS Simulator เราจะรันบนเว็บเบราว์เซอร์โดยคลิก Run in Web Browser

import { StatusBar } from 'expo-status-bar'; import React from 'react'; import { StyleSheet, Text, View } from 'react-native'; export default function App() { return ( <View style={styles.container}> <Text>Open up App.js to start working on your app!</Text> <StatusBar style="auto" /> </View> ); } const styles = StyleSheet.create({ container: { flex: 1, backgroundColor: '#fff', alignItems: 'center', justifyContent: 'center', }, }); 
ไฟล์ App.js เริ่มต้น

นี่คือไฟล์ App.js เริ่มต้นที่มีโค้ดพื้นฐาน

สร้างแอปข่าว Android ที่แข็งแกร่งด้วย React Native และ Native Base
ผลลัพธ์เริ่มต้น

ตอนนี้แอปพลิเคชันของเรากำลังทำงานอยู่แล้ว

สร้างหน้าจอต่างๆ ด้วย React Navigation

ต่อไป เราจะสร้างหน้าจอหลายหน้าสำหรับแอปพลิเคชัน โดยใช้ React Navigation มาติดตั้งกัน

ไปที่ https://reactnavigation.org/ และคลิก Read Docs เพื่อเปิดหน้าเอกสาร

ติดตั้ง React Navigation ด้วยคำสั่ง:

npm install @react-navigation/native expo install react-native-screens react-native-safe-area-context
ติดตั้ง React Navigation

เราจะใช้ bottomTabNavigator จากเมนูซ้ายเลือก API Reference > Navigators > Bottom Tabs

สร้างแอปข่าว Android ที่แข็งแกร่งด้วย React Native และ Native Base
เลือก Bottom Tabs

ติดตั้ง Bottom Tabs:

npm install @react-navigation/bottom-tabs
ติดตั้ง Bottom Tabs

ใน App.js ให้นำเข้า Bottom Tabs:

import { createBottomTabNavigator } from '@react-navigation/bottom-tabs'; 
นำเข้า Bottom Tabs

นำเข้า Tab Screens:

import { createBottomTabNavigator } from '@react-navigation/bottom-tabs'; import { NavigationContainer } from '@react-navigation/native'; const Tab = createBottomTabNavigator(); function MyTabs() { return ( <Tab.Navigator> <Tab.Screen name="Home" component={HomeScreen} /> <Tab.Screen name="Settings" component={SettingsScreen} /> </Tab.Navigator> ); }
นำเข้า Tab Navigator Screens

สำหรับแอปของเรา เราต้องการหน้าจอดังนี้:

<Tab.Navigator> <Tab.Screen name="All" component={All} /> <Tab.Screen name="Business" component={Business} /> <Tab.Screen name="Health" component={HealthScreen} /> <Tab.Screen name="Sports" component={SportsScreen} /> <Tab.Screen name="Tech" component={TechScreen} /> </Tab.Navigator>

เราต้องสร้างหน้าจอสำหรับแท็บ: All News, Business News, Sports News, Health News, และ Tech News พร้อมสร้างคอมโพเนนต์สำหรับแต่ละหน้าจอในโปรเจกต์

ห่อ TabNavigator ไว้ใน NavigationContainer:

<NavigationContainer> <Tab.Navigator> <Tab.Screen name="All" component={All} /> <Tab.Screen name="Business" component={Business} /> <Tab.Screen name="Health" component={HealthScreen} /> <Tab.Screen name="Sports" component={SportsScreen} /> <Tab.Screen name="Tech" component={TechScreen} /> </Tab.Navigator> </NavigationContainer>

นำเข้าโมดูลหน้าจอทั้งหมด:

import All from './screens/All'; import Business from './screens/Business'; import HealthScreen from './screens/Health'; import SportsScreen from './screens/Sports'; import TechScreen from './screens/Tech';

รวมโค้ดทั้งหมด:

import React from 'react'; import { createBottomTabNavigator } from '@react-navigation/bottom-tabs'; import { NavigationContainer } from '@react-navigation/native'; import All from './screens/All'; import Business from './screens/Business'; import HealthScreen from './screens/Health'; import SportsScreen from './screens/Sports'; import TechScreen from './screens/Tech'; const Tab = createBottomTabNavigator(); export default function App() { return ( <NavigationContainer> <Tab.Navigator> <Tab.Screen name="All" component={All} /> <Tab.Screen name="Business" component={Business} /> <Tab.Screen name="Health" component={HealthScreen} /> <Tab.Screen name="Sports" component={SportsScreen} /> <Tab.Screen name="Tech" component={TechScreen} /> </Tab.Navigator> </NavigationContainer> ); } 
โค้ดสำหรับหน้าจอทั้งหมด

ผลลัพธ์จะได้ 5 หน้าจอ:

สร้างแอปข่าว Android ที่แข็งแกร่งด้วย React Native และ Native Base
ห้าหน้าจอ ได้แก่ All, Business, Health, Sports และ Tech

ตอนนี้เรามี 5 หน้าจอ เราจะปรับไอคอนสำหรับ Bottom Tabs โดยใช้ไลบรารีไอคอน react-native-elements

ติดตั้งด้วยคำสั่ง:

npm install react-native-elements
ติดตั้ง React Native Elements

แพ็กเกจนี้มีไอคอนให้เลือกมากมาย

สร้างแอปข่าว Android ที่แข็งแกร่งด้วย React Native และ Native Base
ไอคอนที่มีใน React Native Elements

เพิ่มไอคอนใน Bottom Tab Navigator:

<Tab.Screen name="All" component={All} options={{ tabBarIcon: (props) => ( <Icon type='feather' name='home' color={props.color} /> ), }} />
เพิ่มไอคอนหน้า Home

เราเพิ่มไอคอน "home" ประเภท feather สำหรับหน้าแรก

สร้างแอปข่าว Android ที่แข็งแกร่งด้วย React Native และ Native Base
Bottom Tab Navigator พร้อมไอคอน Home

ทำซ้ำสำหรับแท็บอื่นๆ:

<Tab.Navigator> <Tab.Screen name="All" component={All} options={{ tabBarIcon: (props) => ( <Icon type='feather' name='home' color={props.color} /> ), }} /> <Tab.Screen name="Business" component={Business} options={{ tabBarIcon: (props) => ( <Icon type='feather' name='dollar-sign' color={props.color} /> ), }} /> <Tab.Screen name="Health" component={HealthScreen} options={{ tabBarIcon: (props) => ( <Icon type='feather' name='heart' color={props.color} /> ), }} /> <Tab.Screen name="Sports" component={SportsScreen} options={{ tabBarIcon: (props) => ( <Icon type='ionicon' name="tennisball-outline" color={props.color} /> ), }} /> <Tab.Screen name="Tech" component={TechScreen} options={{ tabBarIcon: (props) => ( <Icon type='ionicon' name="hardware-chip-outline" color={props.color} /> ), }} /> </Tab.Navigator>
Bottom Tabs ทั้งหมดพร้อมไอคอน
สร้างแอปข่าว Android ที่แข็งแกร่งด้วย React Native และ Native Base

ตอนนี้แต่ละแท็บมีไอคอนเฉพาะตัวแล้ว

เรียกใช้ News API

เราจะเรียก News API จาก https://newsapi.org/

สร้างแอปข่าว Android ที่แข็งแกร่งด้วย React Native และ Native Base

สมัครสมาชิกเว็บไซต์เพื่อรับ API Key

สร้างไฟล์ config เพื่อเก็บค่าคงที่ของข่าว:

export const API_KEY = ``; export const endpoint = `https://newsapi.org/v2/top-headlines`; export const country = 'in'
ไฟล์ config.js

เราต้องการ API_KEY, endpoint, และรหัสประเทศ

สร้างบริการสำหรับ GET API Request ในไฟล์ services.js

นำเข้า config ที่ด้านบน:

import { API_KEY, endpoint, country } from '../config/config';
Services.js

เขียนฟังก์ชันบริการ:

export async function services(category = 'general') { let articles = await fetch(`${endpoint}?country=${country}&category=${category}`, { headers: { 'X-API-KEY': API_KEY } }); let result = await articles.json(); articles = null; return result.articles; }
บริการ GET API

เราดึงข้อมูลข่าวโดยใช้ endpoint พร้อมพารามิเตอร์ country และ category ฟังก์ชันรับ category เป็น general เป็นค่าเริ่มต้น ส่ง API Key ใน headers แปลง response เป็น JSON และคืนค่า articles

ไฟล์เต็มสำหรับอ้างอิง:

import { API_KEY, endpoint, country } from '../config/config'; export async function services(category = 'general') { let articles = await fetch(`${endpoint}?country=${country}&category=${category}`, { headers: { 'X-API-KEY': API_KEY } }); let result = await articles.json(); articles = null; return result.articles; }

นำเข้า service ใน All.js:

import { services } from '../services/services';
นำเข้า Services เข้า All.js

ใช้ Hooks useState และ useEffect useEffect จะเรียก service และ useState จะเก็บ response จาก API

import React, { useEffect, useState } from 'react' import { View } from 'react-native'; import { services } from '../services/services'; export default function All() { const [newsData, setNewsData] = useState([]) useEffect(() => { services('general') .then(data => { setNewsData(data) }) .catch(error => { alert(error) }) }, []) return ( <View> </View> ) } 
ใช้ useState และ useEffect hooks

ในไฟล์นี้ เราเรียก services ใน useEffect hook เก็บ response ใน state newsData (array) ส่งพารามิเตอร์ category เป็น general เนื่องจากหน้านี้แสดงข่าวทั้งหมด สำหรับหน้าอื่นจะเปลี่ยน category ตามนั้น เช่น health, sports เป็นต้น

ตอนนี้เราต้องแสดงข้อมูลใน UI ต้องใช้แพ็กเกจ Native Base มาติดตั้งกัน

ติดตั้ง Native Base:

yarn add native-base styled-components styled-system expo install react-native-svg react-native-safe-area-context
ติดตั้ง Native Base

ใน All.js นำเข้าจาก Native Base:

import React, { useEffect, useState } from 'react' import { View, Text } from 'react-native'; import { NativeBaseProvider, FlatList, ScrollView, Divider, Image, Spinner } from 'native-base'; import { services } from '../services/services';
นำเข้าจาก Native Base

เพิ่ม NativeBaseProvider ใน return:

return ( <NativeBaseProvider> </NativeBaseProvider> )
เพิ่ม NativeBaseProvider ใน return

เพิ่ม ScrollView เพื่อให้เลื่อนได้เมื่อข่าวเยอะ:

<NativeBaseProvider> <ScrollView height={850}> </ScrollView> </NativeBaseProvider>
เพิ่ม ScrollView

เพิ่ม FlatList เพื่อแสดงข้อมูลข่าว:

<NativeBaseProvider> <ScrollView height={850}> <FlatList data={newsData} renderItem={({ item }) => ( <View> </View> )} keyExtractor={(item) => item.id} /> </ScrollView> </NativeBaseProvider>
ใช้ FlatList

FlatList รับ prop data เป็น newsData state และส่งคืน item จาก renderItem คล้าย map ใน JavaScript มี keyExtractor เพื่อทำให้แต่ละ item unik

แสดงข้อมูลใน View:

<NativeBaseProvider> <ScrollView height={850}> <FlatList data={newsData} renderItem={({ item }) => ( <View> <View> </View> </View> )} keyExtractor={(item) => item.id} /> </ScrollView> </NativeBaseProvider>

เพิ่ม Text ภายใน child view:

<NativeBaseProvider> <ScrollView height={850}> <FlatList data={newsData} renderItem={({ item }) => ( <View> <View> <Text> {item.title} </Text> <Text> {item.publishedAt} </Text> <Text> {item.description} </Text> </View> </View> )} keyExtractor={(item) => item.id} /> </ScrollView> </NativeBaseProvider>

แสดงหัวข้อข่าว คำอธิบาย และวันที่เผยแพร่

สร้างแอปข่าว Android ที่แข็งแกร่งด้วย React Native และ Native Base

จัดสไตล์แอปข่าว React Native

ตอนนี้แอปมีหัวข้อ คำอธิบาย และวันที่ แต่เราต้องจัดสไตล์ให้สวยงามขึ้น

นำเข้า StyleSheet จาก React Native:

import { View, Text, StyleSheet } from 'react-native';
นำเข้า StyleSheet จาก react-native
<View> <View style={styles.newsContainer}> <Text style={styles.title}> {item.title} </Text> <Text style={styles.date}> {item.publishedAt} </Text> <Text style={styles.newsDescription}> {item.description} </Text> </View> </View>

เพิ่มสไตล์:

const styles = StyleSheet.create({ newsContainer: { padding: 10 }, title: { fontSize: 18, marginTop: 10, fontWeight: "600" }, newsDescription: { fontSize: 16, marginTop: 10 }, date: { fontSize: 14 }, });
StyleSheet ใน All.js
สร้างแอปข่าว Android ที่แข็งแกร่งด้วย React Native และ Native Base

แอปดูดีขึ้นแล้ว และเลื่อนได้อีกด้วย

เปลี่ยนรูปแบบวันที่ให้อ่านง่ายขึ้น เพราะ '2021-08-21T11:00:40Z' อ่านยาก เราจะใช้ moment.js

ติดตั้ง moment.js:

npm install moment --save
ติดตั้ง Moment.js เพื่อจัดรูปแบบเวลา

นำเข้าใน All.js และจัดรูปแบบ:

<Text style={styles.date}> {moment(item.publishedAt).format('LLL')} </Text>
จัดรูปแบบวันที่และเวลาด้วย moment.js

เลือกฟอร์แมต 'LLL' จากเอกสาร moment

สร้างแอปข่าว Android ที่แข็งแกร่งด้วย React Native และ Native Base
รูปแบบวันที่และเวลาของ Moment.js
สร้างแอปข่าว Android ที่แข็งแกร่งด้วย React Native และ Native Base

ตอนนี้วันที่อ่านง่ายขึ้นแล้ว

เพิ่ม Divider แยกข่าวแต่ละรายการ:

<View> <View style={styles.newsContainer}> <Text style={styles.title}> {item.title} </Text> <Text style={styles.date}> {moment(item.publishedAt).format('LLL')} </Text> <Text style={styles.newsDescription}> {item.description} </Text> </View> <Divider my={2} bg="#e0e0e0" /> </View>
เพิ่ม Divider
สร้างแอปข่าว Android ที่แข็งแกร่งด้วย React Native และ Native Base

ข่าวถูกแยกด้วยเส้น Divider ดูเรียบร้อยแล้ว

News API มีรูปภาพด้วย มาเพิ่มกัน:

<View> <View style={styles.newsContainer}> <Image width={550} height={250} resizeMode={"cover"} source={{ uri: item.urlToImage, }} alt="Alternate Text" /> <Text style={styles.title}> {item.title} </Text> <Text style={styles.date}> {moment(item.publishedAt).format('LLL')} </Text> <Text style={styles.newsDescription}> {item.description} </Text> </View> <Divider my={2} bg="#e0e0e0" /> </View>

ใช้ key urlToImage สำหรับรูปภาพ

สร้างแอปข่าว Android ที่แข็งแกร่งด้วย React Native และ Native Base

ตอนนี้มีรูปภาพข่าวแสดงแล้ว

เพิ่ม Spinner แสดงสถานะกำลังโหลดข่าว

เพิ่ม Spinner ขณะโหลดข่าว

ตรวจสอบ ถ้า newsData length > 1 แสดง FlatList มิฉะนั้นแสดง Spinner

{newsData.length > 1 ? ( <FlatList data={newsData} renderItem={({ item }) => ( <View> <View style={styles.newsContainer}> <Image width={550} height={250} resizeMode={"cover"} source={{ uri: item.urlToImage, }} alt="Alternate Text" /> <Text style={styles.title}> {item.title} </Text> <Text style={styles.date}> {moment(item.publishedAt).format('LLL')} </Text> <Text style={styles.newsDescription}> {item.description} </Text> </View> <Divider my={2} bg="#e0e0e0" /> </View> )} keyExtractor={(item) => item.id} /> ) : ( <View style={styles.spinner}> <Spinner color="danger.400" /> </View> )}
เพิ่ม Spinner

เพิ่มสไตล์สำหรับ Spinner:

spinner: { display: 'flex', justifyContent: 'center', alignItems: 'center', height: 400 }
สไตล์สำหรับ Spinner

โค้ดเต็มของ All.js:

import React, { useEffect, useState } from 'react' import { View, Text, StyleSheet } from 'react-native'; import { NativeBaseProvider, FlatList, ScrollView, Divider, Image, Spinner } from 'native-base'; import { services } from '../services/services'; import moment from 'moment' export default function All() { const [newsData, setNewsData] = useState([]) useEffect(() => { services('general') .then(data => { setNewsData(data) }) .catch(error => { alert(error) }) }, []) return ( <NativeBaseProvider> <ScrollView height={850}> {newsData.length > 1 ? ( <FlatList data={newsData} renderItem={({ item }) => ( <View> <View style={styles.newsContainer}> <Image width={550} height={250} resizeMode={"cover"} source={{ uri: item.urlToImage, }} alt="Alternate Text" /> <Text style={styles.title}> {item.title} </Text> <Text style={styles.date}> {moment(item.publishedAt).format('LLL')} </Text> <Text style={styles.newsDescription}> {item.description} </Text> </View> <Divider my={2} bg="#e0e0e0" /> </View> )} keyExtractor={(item) => item.id} /> ) : ( <View style={styles.spinner}> <Spinner color="danger.400" /> </View> )} </ScrollView> </NativeBaseProvider> ) } const styles = StyleSheet.create({ newsContainer: { padding: 10 }, title: { fontSize: 18, marginTop: 10, fontWeight: "600" }, newsDescription: { fontSize: 16, marginTop: 10 }, date: { fontSize: 14 }, spinner: { display: 'flex', justifyContent: 'center', alignItems: 'center', height: 400 } });

หน้า All.js เสร็จสมบูรณ์แล้ว เราสามารถนำโค้ดเดียวกันไปใช้ในหน้าอื่นได้ โดยเปลี่ยนพารามิเตอร์ใน services ใส่ useEffect hook

สำหรับหน้า Business ใช้ 'business', Health ใช้ 'health', Sports ใช้ 'sports', Tech ใช้ 'technology'

useEffect(() => { services('business') .then(data => { setNewsData(data) }) .catch(error => { alert(error) }) }, [])
สำหรับ Business
useEffect(() => { services('health') .then(data => { setNewsData(data) }) .catch(error => { alert(error) }) }, [])
สำหรับ Health
useEffect(() => { services('sports') .then(data => { setNewsData(data) }) .catch(error => { alert(error) }) }, [])
สำหรับ Sports
useEffect(() => { services('technology') .then(data => { setNewsData(data) }) .catch(error => { alert(error) }) }, [])
สำหรับ Tech

สรุป

ยินดีด้วย! แอปพลิเคชันข่าวของเราเสร็จสมบูรณ์แล้ว

ลองสร้างและทดลองปรับแต่งดู มีอะไรให้ทำอีกมากมาย

ดูเพลย์ลิสต์สร้างแอปข่าวด้วย React Native และ Native Base บนช่อง YouTube ของผม

ดาวน์โหลดโค้ดได้ที่: https://github.com/nishant-666/React-Native-News

Happy Learning.