模拟淘宝首页

// react/react-native
import React from 'react'
import {
SafeAreaView,
ScrollView,
Text,
View,
Image,
StatusBar,
NativeModules,
useColorScheme,
Platform,
} from 'react-native'
// 获取安全区工具,自测只有ios好使
import {useSafeAreaInsets} from "react-native-safe-area-context";
// react-navigation
import {createStackNavigator} from "@react-navigation/stack";
const {Navigator: StackNavigator, Screen: StackScreen} = createStackNavigator();
// 页面
import Subscribe from '../../screens/Home/Subscribe';
import Recommend from '../../screens/Home/Recommend';
// 自定义HeaderLeft,Header,HeaderRight组件
import CustomHeaderLeft from './components/CustomHeaderLeft'
import CustomHeader from './components/CustomHeader'
import CustomHeaderRight from './components/CustomHeaderRight'
// 定义Navigator配置文件
const optionsConfig = (prop) => {
// 动态获取状态栏高度
const getStatusHeight:any = () => {
if (Platform.OS === 'ios') {
console.log('StatusBarMessage',useSafeAreaInsets());
return useSafeAreaInsets().top
} else {
console.log('StatusBarMessage',StatusBar.currentHeight)
// 由于安卓的header高度不包含状态栏高度,所以直接返回0,android刘海屏带测试
return 0 //StatusBar.currentHeight
}
};
return {
// 直接将prop传给组件,
// 注意 headerLeft: (prop) => <CustomHeaderLeft {...prop}/>, 不可取,亲测这种方式子组件获取不到navigation对象
headerLeft: () => <CustomHeaderLeft {...prop}/>,
headerTitle: () => <CustomHeader {...prop}/>,
headerRight: () => <CustomHeaderRight {...prop}/>,
headerMode: 'screen',
// header整体样式设置
headerStyle: {
// header容器高度+状态栏高度,android不需要加状态栏高度
height: 80 + getStatusHeight(),
borderBottomWidth: 0,
elevation: 0
// backgroundColor:'blue',
},
// 左、中、右容器样式设置,高度均不含状态栏高度
headerLeftContainerStyle: {
height: 40,
paddingLeft: 10
},
headerTitleContainerStyle:{
paddingLeft:30,
paddingRight:30,
height:80
},
headerRightContainerStyle: {
height: 40,
paddingRight: 10
},
}
};
const HomeStack = () => {
return (
<StackNavigator screenOptions={optionsConfig}>
<StackScreen name={'Subscribe'} component={Subscribe}/>
<StackScreen name={'Recommend'} component={Recommend}/>
</StackNavigator>
)
};
export default HomeStack
CustomHeaderLeft
import React, {useState} from 'react'
import {
SafeAreaView,
ScrollView,
Text,
View,
Image,
StatusBar,
useColorScheme,
Platform,
StyleSheet,
TouchableWithoutFeedback
} from 'react-native'
import {Iconfont} from "../../../../assets/font";
const CustomHeaderLeft = () => {
return (
<SafeAreaView style={styles.safe}>
<TouchableWithoutFeedback>
<View style={[styles.container]}>
<Iconfont name="TRP-qiandao" size={20} color={'#F41B0C'}/>
<View style={{paddingLeft:4,paddingRight:10}}>
<Text style={{color:'#E1613C',fontWeight:'500'}}>签到</Text>
</View>
</View>
</TouchableWithoutFeedback>
</SafeAreaView>
)
};
const styles = StyleSheet.create({
safe:{
flex:1,
// backgroundColor:'yellow'
},
container: {
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
flexDirection: "row",
backgroundColor:'#FCEEDB',
marginTop:6,
marginBottom:6,
paddingLeft:4,
height:28,
borderRadius:14
}
})
export default CustomHeaderLeft
CustomHeader
import React, {useState} from 'react'
import {
SafeAreaView,
ScrollView,
Text,
View,
Image,
StatusBar,
NativeModules,
useColorScheme,
Platform,
StyleSheet,
TouchableOpacity,
TouchableWithoutFeedback,
Dimensions
} from 'react-native'
import CustomHeaderInput from './CustomHeaderInput'
const CustomHeader = (prop) => {
const [data, setData] = useState([
{
name: '订阅',
isActive: true
},
{
name: '推荐',
isActive: false
}
]);
const {width, height, scale} = Dimensions.get('window');
const left:number = Math.floor((width - 146-20) / 2);
// console.log('计算偏移量', width, height, scale, left)
const click: any = (i) => {
setData((data: any): any => {
return data.map((em, index) => {
if (index === i) {
em.isActive = true
} else {
em.isActive = false
}
return em
})
});
console.warn(data)
};
return (
<SafeAreaView style={styles.safe}>
<View style={styles.flexCloumn}>
<View style={[styles.positionR]}>
<View style={styles.title}>
{
data.map((em, index) => {
return (
<TouchableOpacity key={index} onPress={() => {
click(index)
}}>
<View style={styles.item}>
<Text style={[styles.text, (() => {
if (em.isActive) return styles.active;
return;
})()]}>{em.name}</Text>
</View>
</TouchableOpacity>
)
})
}
</View>
<View style={[styles.positionA, styles.bottomLine, (() => {
const i = data.findIndex(em => em.isActive);
if (i === 0) {
return {left: 25}
} else {
return {right: 25}
}
})()]}></View>
<View style={{position: 'absolute', left: -left, right: left, bottom: -34}}>
<CustomHeaderInput {...prop}/>
</View>
</View>
</View>
</SafeAreaView>
)
};
const styles = StyleSheet.create({
safe: {
// flex: 1,
// backgroundColor:'gray',
},
flexCloumn: {
// flex: 1,
// display: 'flex',
// justifyContent: 'flex-start',
alignItems: 'center',
flexDirection: "column",
// backgroundColor:'red'
},
title: {
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
flexDirection: "row",
// height: 40,
// backgroundColor: 'gray'
},
item: {
paddingLeft: 15,
paddingRight: 15,
height:40,
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
flexDirection: "row",
},
itemActive: {},
text: {
fontSize: 20,
color:'#333'
},
positionR: {
position: 'relative'
},
positionA: {
position: 'absolute'
},
bottomLine: {
width: 24,
height: 2,
backgroundColor: '#E1613C',
borderRadius: 1,
bottom: 2,
right: 25//23
},
active: {
fontWeight: '500',
fontSize: 22,
color: '#E1613C'
}
})
export default CustomHeader
CustomHeaderRight
import React, {useState} from 'react'
import {
SafeAreaView,
ScrollView,
Text,
View,
Image,
StatusBar,
useColorScheme,
Platform,
StyleSheet,
TouchableWithoutFeedback
} from 'react-native'
import {Iconfont} from "../../../../assets/font";
const CustomHeaderLeft = ({route,navigation}) => {
return (
<SafeAreaView style={styles.safe}>
<TouchableWithoutFeedback>
<View style={[styles.container]}>
<Iconfont name="TRP-huiyuanma" size={20} color={'#F41B0C'}/>
<View style={{paddingLeft: 4, paddingRight: 10}}>
<Text style={{color: '#E1613C', fontWeight: '500'}}>会员码</Text>
</View>
</View>
</TouchableWithoutFeedback>
</SafeAreaView>
)
};
const styles = StyleSheet.create({
safe:{
flex:1,
height:28,
// backgroundColor:'green'
},
container: {
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
flexDirection: "row",
backgroundColor: '#FCEEDB',
marginTop: 6,
marginBottom: 6,
paddingLeft:10,
height: 28,
borderRadius: 14
}
})
export default CustomHeaderLeft
CustomHeaderInput
import React, {useState} from 'react'
import {
SafeAreaView,
ScrollView,
Text,
View,
Image,
StatusBar,
useColorScheme,
Platform,
StyleSheet,
TouchableWithoutFeedback,
TextInput,
Dimensions
} from 'react-native'
import {Iconfont} from "../../../../assets/font";
const CustomHeaderInput = ({route,navigation}) => {
const {width, height, scale} = Dimensions.get('window');
return (
<SafeAreaView style={styles.safe}>
<TouchableWithoutFeedback>
<View style={[styles.container,{width:width-20}]}>
<View style={styles.saoma}><Iconfont name="TRP-Scancode" size={20} color={'#F41B0C'}/></View>
<TextInput style={styles.input}
placeholder={'短裤裙女夏'}
caretHidden={false}
clearButtonMode={'while-editing'}
autoCompleteType={'off'}
editable={false}
/>
<TouchableWithoutFeedback onPress={()=>{
console.log('点击事件进来了')
console.warn(navigation)
navigation.navigate('Camera')
}}>
<View style={styles.xiangji}><Iconfont name="TRP-xiangji" size={20} color={'#F41B0C'}/></View>
</TouchableWithoutFeedback>
<View style={styles.button}>
<Text style={styles.buttonText}>搜索</Text>
</View>
</View>
</TouchableWithoutFeedback>
</SafeAreaView>
)
};
const styles = StyleSheet.create({
safe: {
flex: 1,
},
container: {
display: 'flex',
justifyContent: 'space-between',
alignItems: 'center',
flexDirection: "row",
height: 30,
borderRadius: 15,
borderWidth: 1,
borderColor: '#F41B0C',
},
input: {
flex: 1,
padding: 0
},
saoma: {
paddingLeft: 10,
paddingRight: 10
},
xiangji: {
paddingLeft: 10,
paddingRight: 10
},
button: {
width: 60,
height: 26,
backgroundColor: '#F41B0C',
borderRadius: 13,
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
flexDirection: 'row',
marginRight: 1,
},
buttonText: {
color: '#fff'
}
})
export default CustomHeaderInput
网友评论