iT邦幫忙

2024 iThome 鐵人賽

DAY 7
0
Mobile Development

從零開始學React Native系列 第 7

【從零開始學React Native】6. 創建Todo Tracker——創建頁面

  • 分享至 

  • xImage
  •  

現在我們先看一下我們使用React Native Cli建立出來的專案架構。

https://ithelp.ithome.com.tw/upload/images/20240921/201089316t8fMUqoGl.png

現在我們執行指令啟動專案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;

https://ithelp.ithome.com.tw/upload/images/20240921/20108931xSjY3f8MKT.png

現在我們來照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;

畫面如下:

https://ithelp.ithome.com.tw/upload/images/20240921/201089310r71bTqoVc.png


上一篇
【從零開始學React Native】5. 創建Todo Tracker——規劃
下一篇
【從零開始學React Native】7. 創建Todo Tracker——創建其他頁面
系列文
從零開始學React Native20
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言