現在我們先看一下我們使用React Native Cli建立出來的專案架構。
現在我們執行指令啟動專案pnpm run start
,並在終端上點a
啟動android,如果不行執行pnpm run android
。如果在出現問題,執行npx react-native doctor
來看,在透過doctor來fix(通常是JDK和Android SDK版本不符的問題)
我們先在跟目錄創建src,並創建components和pages兩個目錄。
-
--src
----components
----pages
我們先創建我們的首頁,先在pages創建home.page.tsx
,並且對App.tsx
進行調整。
import React, { PropsWithChildren } from 'react'
import { View, Text, StyleSheet } from 'react-native';
import { Colors } from 'react-native/Libraries/NewAppScreen';
const styles = StyleSheet.create({
homeContainer: {
marginTop: 32,
paddingHorizontal: 24,
},
homeTitle: {
fontSize: 24,
fontWeight: '600',
},
homeDescription: {
marginTop: 8,
fontSize: 18,
fontWeight: '400',
},
highlight: {
fontWeight: '700',
},
});
type HomePageProps = PropsWithChildren<{
isDarkMode?: boolean;
}>;
const HomePage = ({children, isDarkMode = false}: HomePageProps) => {
return (
<View style={styles.homeContainer}>
<Text
style={[
styles.homeTitle,
]}>
Home
</Text>
<Text
style={[
styles.homeDescription,
{
color: isDarkMode ? Colors.light : Colors.dark,
},
]}>
{children}
</Text>
</View>
);
}
export default HomePage
/**
* Sample React Native App
* https://github.com/facebook/react-native
*
* @format
*/
import React from 'react';
import {
SafeAreaView,
ScrollView,
StatusBar,
useColorScheme,
} from 'react-native';
import {
Colors,
} from 'react-native/Libraries/NewAppScreen';
import HomePage from './src/pages/home.page';
function App(): React.JSX.Element {
const isDarkMode = useColorScheme() === 'dark';
const backgroundStyle = {
backgroundColor: isDarkMode ? Colors.darker : Colors.lighter,
};
return (
<SafeAreaView style={backgroundStyle}>
<StatusBar
barStyle={isDarkMode ? 'light-content' : 'dark-content'}
backgroundColor={backgroundStyle.backgroundColor}
/>
<ScrollView
contentInsetAdjustmentBehavior="automatic"
style={backgroundStyle}
>
<HomePage />
</ScrollView>
</SafeAreaView>
);
}
export default App;
現在我們來照mock簡易創建,這裡先安裝react-native-safe-area-contex套件pnpm add react-native-safe-area-context
src\pages\home.page.tsx:
import React, { PropsWithChildren } from 'react';
import { View, Text, TextInput, FlatList, StyleSheet } from 'react-native';
import { Colors } from 'react-native/Libraries/NewAppScreen';
const styles = StyleSheet.create({
container: {
flex: 1,
padding: 10,
},
title: {
fontSize: 18,
fontWeight: 'bold',
marginBottom: 10,
},
searchBar: {
height: 40,
borderColor: 'gray',
borderWidth: 1,
borderRadius: 5,
paddingHorizontal: 10,
marginBottom: 10,
},
taskList: {
flex: 1,
},
taskItem: {
padding: 10,
borderBottomWidth: 1,
borderBottomColor: '#ccc',
},
});
type Task = {
id: string;
title: string;
}
type HomePageProps = PropsWithChildren<{
isDarkMode?: boolean;
}>;
const HomePage = ({children, isDarkMode = false}: HomePageProps) => {
const tasks: Task[] = [
{ id: '1', title: 'Task 1' },
{ id: '2', title: 'Task 2' },
{ id: '3', title: 'Task 3' },
];
const renderTask = ({ item }: { item: Task }) => (
<View style={styles.taskItem}>
<Text>{item.title}</Text>
</View>
);
return (
<View style={styles.container}>
<Text style={styles.title}>主畫面 (任務列表)</Text>
<TextInput
style={styles.searchBar}
placeholder="搜索欄"
placeholderTextColor={isDarkMode ? Colors.light : Colors.dark}
/>
<FlatList
style={styles.taskList}
data={tasks}
renderItem={renderTask}
keyExtractor={item => item.id}
/>
</View>
);
};
export default HomePage;
App.tsx:
/**
* Sample React Native App
* https://github.com/facebook/react-native
*
* @format
*/
import React, { useState } from 'react';
import { SafeAreaView, StatusBar, useColorScheme, View, Text, TouchableOpacity, StyleSheet } from 'react-native';
import { Colors } from 'react-native/Libraries/NewAppScreen';
import HomePage from './src/pages/home.page';
function App(): React.JSX.Element {
const isDarkMode = useColorScheme() === 'dark';
const [currentPage, setCurrentPage] = useState('home');
const backgroundStyle = {
backgroundColor: isDarkMode ? Colors.darker : Colors.lighter,
flex: 1,
};
const renderPage = () => {
switch (currentPage) {
case 'home':
return <HomePage isDarkMode={isDarkMode} />;
case 'add':
return <Text>新增任務頁面</Text>;
case 'stats':
return <Text>統計頁面</Text>;
case 'settings':
return <Text>設置頁面</Text>;
default:
return <HomePage isDarkMode={isDarkMode} />;
}
};
return (
<SafeAreaView style={backgroundStyle}>
<StatusBar
barStyle={isDarkMode ? 'light-content' : 'dark-content'}
backgroundColor={backgroundStyle.backgroundColor}
/>
<View style={styles.container}>
{renderPage()}
</View>
<View style={styles.bottomNav}>
<TouchableOpacity style={styles.navItem} onPress={() => setCurrentPage('home')}>
<Text style={styles.navText}>主頁</Text>
</TouchableOpacity>
<TouchableOpacity style={styles.navItem} onPress={() => setCurrentPage('add')}>
<Text style={styles.navText}>新增</Text>
</TouchableOpacity>
<TouchableOpacity style={styles.navItem} onPress={() => setCurrentPage('stats')}>
<Text style={styles.navText}>統計</Text>
</TouchableOpacity>
<TouchableOpacity style={styles.navItem} onPress={() => setCurrentPage('settings')}>
<Text style={styles.navText}>設置</Text>
</TouchableOpacity>
</View>
</SafeAreaView>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
},
bottomNav: {
flexDirection: 'row',
justifyContent: 'space-around',
alignItems: 'center',
height: 50,
borderTopWidth: 1,
borderTopColor: '#ccc',
backgroundColor: '#f8f8f8',
},
navItem: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
height: '100%',
},
navText: {
fontSize: 12,
},
});
export default App;
畫面如下: