Taxi App UI 3

윤수환·2025년 3월 16일

React Native

목록 보기
10/26

패키지 추가
npm install react-native-responsive-screen

주의사항
return 어디에 들어가는지 잘 확인하기

변경점
Main_Map

import { JSX } from "react";
import { SafeAreaView, StyleSheet, Text, View, TextInput, TouchableOpacity } from "react-native";
import Icon from 'react-native-vector-icons/FontAwesome';
import { widthPercentageToDP as wp, heightPercentageToDP as hp } from "react-native-responsive-screen";
import { useState } from 'react';

function Main_Map() : JSX.Element {
    console.log("-- Main_Map()")

    const [showBtn, setShowBtn] = useState(false)

    const handleLongPress = async(event:any) => {
        setShowBtn(true)
    }

    const handleAddMarker = (title:string) => {
        setShowBtn(false)
    }

    return (
        <SafeAreaView style={styles.container}>
            <View style={[styles.container, {transform: [{scaleX:1}, {scaleY:2}]} ] }>
                <Icon name ="building" size={300} color={'#34db98'}
                onPress={() => {setShowBtn(false)}}
                onLongPress={handleLongPress}/>
            </View>

            <View style={{position:'absolute', width:'100%', height:'100%', padding:10}}>
                <View style={{flexDirection:'row'}}>
                    <View style={{flex:1}}>
                        <TextInput style={styles.input} placeholder={'출발지'}/>
                        <TextInput style={styles.input} placeholder={'도착지'}/>
                    </View>
                    <TouchableOpacity style={[styles.button, {marginLeft:10, justifyContent:'center'}]}>
                        <Text style={styles.buttonText}>호출</Text>
                    </TouchableOpacity>
                </View>
            </View>

            <TouchableOpacity style={[{position:'absolute', bottom:20, right:20}]}>
                <Icon name="crosshairs" size={40} color={'#3498db'}/>
            </TouchableOpacity>

            <View style={{position:'absolute', top: hp(50)-45, left: wp(50)-75, height:90, width:150}}>
                <TouchableOpacity style={[styles.button, {flex:1, marginVertical:1}]}
                onPress={()=>handleAddMarker('출발지')}
                >
                    <Text style={styles.buttonText}>출발지로 등록</Text>
                </TouchableOpacity>
                <TouchableOpacity style={[styles.button, {flex:1}]}
                onPress={()=>handleAddMarker('출발지')}
                >
                    <Text style={styles.buttonText}>도착지로 등록</Text>
                </TouchableOpacity>
            </View>

        </SafeAreaView>
    )
}

const styles = StyleSheet.create({
    container: {
        flex: 1,
        justifyContent: 'center',
        alignItems: 'center',
        width: '100%'
    },
    button: {
        backgroundColor: '#3498db',
        paddingVertical: 10,
        paddingHorizontal: 20,
        borderRadius: 5
    },
    buttonDisable: {
        backgroundColor: 'gray',
        paddingVertical: 10,
        paddingHorizontal: 20,
        borderRadius: 5
    },
    buttonText: {
        color: 'white',
        fontSize: 16,
        textAlign: 'center'
    },
    input: {
        height: 40,
        borderWidth: 2,
        borderColor: 'gray',
        marginVertical: 1,
        padding: 10
    }
})

export default Main_Map

Main_List

import React from 'react';
import { JSX } from "react";
import { SafeAreaView, StyleSheet, Text, View, FlatList, RefreshControl, Modal } from "react-native";
import { widthPercentageToDP as wp, heightPercentageToDP as hp } from "react-native-responsive-screen";
import { useState } from 'react';
import { useFocusEffect } from "@react-navigation/native";
import Icon from 'react-native-vector-icons/FontAwesome';

function Main_List() : JSX.Element {
    console.log("-- Main_List()")

    const [callList, setCallList] = useState([])
    const [loading, setLoading] = useState(false)

    useFocusEffect(React.useCallback(() => {
        requestCallList()
    },[]))

    const requestCallList = () => {
        setLoading(true)

        setTimeout(() => {

            let tmp : any = []
    
            for (var i=0;i<10;i++) {
                let row = {id:i, start_addr : '출발주소', end_addr : '도착주소', call_state: 'REQ'}
                tmp.push(row)
            }
            setCallList(tmp)
            setLoading(false)
        }, 200)

    }

    const Header = () => {
        <View style={styles.header}>
            <Text style={[styles.headerText, {width:wp(80)}]}>출발지 / 도착지</Text>
            <Text style={[styles.headerText, {width:wp(20)}]}>상태</Text>
        </View>
    }

    const ListItem = (row:any) => {
        console.log("row = " + JSON.stringify(row))
        return (
            <View style={{flexDirection:'row', marginBottom:5, width:wp(100)}}>
                <View style={{width:wp(80)}}>
                    <Text style={styles.textForm}>{row.item.start_addr}</Text>
                    <Text style={[styles.textForm, {borderTopWidth:0}]}>{row.item.end_addr}</Text>
                </View>
                <View style={{width:wp(20), alignItems:'center', justifyContent:'center'}}>
                    <Text>{row.item.call_state}</Text>
                </View>
            </View>
        )
    }


    return (
        <SafeAreaView style={styles.container}>
            <FlatList style={{flex:1}}
            data={callList}
            ListHeaderComponent={Header}
            renderItem={ListItem}
            keyExtractor={(item:any) => item.id}
            refreshControl={
                <RefreshControl refreshing={loading} onRefresh={requestCallList}/>
            }
            />
            <Modal transparent={true} visible={loading}>
                <View style={{flex:1, justifyContent:'center', alignItems:'center'}}>
                    <Icon name='spinner' size={50} color={'#3498db'}/>
                    <Text style={{color:'black'}}>Loading...</Text>
                </View>
            </Modal>
        </SafeAreaView>
    )
}

const styles = StyleSheet.create({
    container: {
        flex: 1,
        justifyContent: 'center',
        alignItems: 'center',
        width: '100%',
        backgroundColor: 'white'
    },
    header: {
        flexDirection: 'row',
        height: 50,
        marginBottom: 5,
        backgroundColor: '#3498db',
        color: 'white',
        alignItems: 'center'
    },
    headerText: {
        fontSize: 18,
        textAlign: 'center',
        color: 'white'
    },
    textForm: {
        flex: 1,
        borderWidth: 1,
        borderColor: 'white',
        height:hp(5),
        paddingLeft: 10,
        paddingRight: 10
    }
})

export default Main_List

0개의 댓글