基于侧边栏的ViroAR/VR场景导航混合应用实现咨询
Hey there! Nice work laying out the foundation for your drawer-navigated app with mixed AR/VR and regular screens—great start! Let me share some practical examples to flesh out your structure, including a custom sidebar, sample screen components, and refined navigation setup.
1. Refined Navigation Setup (Avoid Duplicate Screen Declarations)
Your current code declares screens in both DrawerNavigator and StackNavigator, which can lead to redundancy. Here's a cleaner approach where we keep all screen definitions in the drawer, using the stack only for top-level navigation needs:
import { DrawerNavigator, StackNavigator } from 'react-navigation'; // Use @react-navigation/native if on v5+ import Home from './screens/Home'; import SignUpScreen from './screens/SignUpScreen'; import HelloWorldScene from './screens/HelloWorldScene'; import HelloWorldSceneAR from './screens/HelloWorldSceneAR'; import HelloWorldSceneVR from './screens/HelloWorldSceneVR'; import ListScreen from './screens/ListScreen'; import ContactUs from './screens/ContactUs'; import AboutUs from './screens/AboutUs'; import SideBar from './components/SideBar'; // Drawer Navigator - all app screens live here const AppDrawer = DrawerNavigator( { Home: { screen: Home }, SignUp: { screen: SignUpScreen }, RegularScene: { screen: HelloWorldScene }, ARScene: { screen: HelloWorldSceneAR }, VRScene: { screen: HelloWorldSceneVR }, List: { screen: ListScreen }, ContactUs: { screen: ContactUs }, AboutUs: { screen: AboutUs }, }, { initialRouteName: "Home", contentOptions: { activeTintColor: "#e91e63", inactiveTintColor: "#333", labelStyle: { fontSize: 16, marginLeft: 10 } }, contentComponent: props => <SideBar {...props} /> } ); // Optional: Stack for modals or deep link handling const AppNavigator = StackNavigator( { Drawer: { screen: AppDrawer }, // Add modals here (e.g., FullScreenAR: { screen: FullScreenAR }) }, { initialRouteName: "Drawer", headerMode: "none" } ); export default () => <Root> <AppNavigator /> </Root>;
2. Custom SideBar Component Example
Since you're using a custom SideBar, here's a functional component with icons and intuitive navigation links:
import React from 'react'; import { View, Text, TouchableOpacity, StyleSheet } from 'react-native'; import { Ionicons } from '@expo/vector-icons'; // Use your preferred icon library const SideBar = ({ navigation }) => { const navigateToScreen = (route) => () => { navigation.navigate(route); navigation.closeDrawer(); }; return ( <View style={styles.container}> <View style={styles.header}> <Text style={styles.headerText}>My App</Text> </View> <View style={styles.navLinks}> <TouchableOpacity style={styles.linkItem} onPress={navigateToScreen('Home')}> <Ionicons name="home" size={24} color="#e91e63" /> <Text style={styles.linkText}>Home</Text> </TouchableOpacity> <TouchableOpacity style={styles.linkItem} onPress={navigateToScreen('RegularScene')}> <Ionicons name="document-text" size={24} color="#333" /> <Text style={styles.linkText}>Regular Scene</Text> </TouchableOpacity> <TouchableOpacity style={styles.linkItem} onPress={navigateToScreen('ARScene')}> <Ionicons name="camera" size={24} color="#333" /> <Text style={styles.linkText}>AR Experience</Text> </TouchableOpacity> <TouchableOpacity style={styles.linkItem} onPress={navigateToScreen('VRScene')}> <Ionicons name="vr" size={24} color="#333" /> <Text style={styles.linkText}>VR Experience</Text> </TouchableOpacity> <TouchableOpacity style={styles.linkItem} onPress={navigateToScreen('List')}> <Ionicons name="list" size={24} color="#333" /> <Text style={styles.linkText}>Item List</Text> </TouchableOpacity> <TouchableOpacity style={styles.linkItem} onPress={navigateToScreen('ContactUs')}> <Ionicons name="mail" size={24} color="#333" /> <Text style={styles.linkText}>Contact Us</Text> </TouchableOpacity> <TouchableOpacity style={styles.linkItem} onPress={navigateToScreen('AboutUs')}> <Ionicons name="information-circle" size={24} color="#333" /> <Text style={styles.linkText}>About Us</Text> </TouchableOpacity> </View> </View> ); }; const styles = StyleSheet.create({ container: { flex: 1, backgroundColor: '#f5f5f5', }, header: { paddingTop: 40, paddingBottom: 20, backgroundColor: '#e91e63', alignItems: 'center', }, headerText: { color: 'white', fontSize: 20, fontWeight: 'bold', }, navLinks: { paddingTop: 20, }, linkItem: { flexDirection: 'row', alignItems: 'center', paddingVertical: 15, paddingHorizontal: 20, }, linkText: { marginLeft: 15, fontSize: 16, color: '#333', }, }); export default SideBar;
3. Sample AR Scene Component (Using Expo AR)
Here's a minimal AR screen example with Expo's AR module (great for quick setup):
import React, { useEffect } from 'react'; import { View, Text, StyleSheet, TouchableOpacity } from 'react-native'; import { AR } from 'expo'; import { ARKit } from 'react-native-arkit'; // Use if targeting iOS native ARKit const HelloWorldSceneAR = ({ navigation }) => { useEffect(() => { // Initialize AR session with horizontal plane detection AR.startAsync({ planeDetection: AR.PlaneDetectionTypes.Horizontal, }); return () => AR.stopAsync(); // Clean up on unmount }, []); return ( <View style={styles.container}> <ARKit style={styles.arView} planeDetection={ARKit.PlaneDetection.Horizontal} lightEstimationEnabled={true} /> <View style={styles.overlay}> <TouchableOpacity style={styles.backButton} onPress={() => navigation.goBack()} > <Text style={styles.backText}>← Back</Text> </TouchableOpacity> <Text style={styles.title}>AR Experience</Text> </View> </View> ); }; const styles = StyleSheet.create({ container: { flex: 1, }, arView: { flex: 1, }, overlay: { position: 'absolute', top: 0, left: 0, right: 0, paddingTop: 40, paddingHorizontal: 20, }, backButton: { padding: 10, backgroundColor: 'rgba(0,0,0,0.5)', borderRadius: 5, }, backText: { color: 'white', fontSize: 16, }, title: { marginTop: 20, color: 'white', fontSize: 22, fontWeight: 'bold', textAlign: 'center', }, }); export default HelloWorldSceneAR;
4. Regular List Screen Example
A simple list screen that integrates seamlessly with your drawer navigation:
import React from 'react'; import { View, Text, StyleSheet, FlatList } from 'react-native'; const ListScreen = () => { const items = [ { id: '1', title: 'Project Alpha' }, { id: '2', title: 'Project Beta' }, { id: '3', title: 'Project Gamma' }, { id: '4', title: 'Project Delta' }, ]; return ( <View style={styles.container}> <Text style={styles.title}>My Projects</Text> <FlatList data={items} keyExtractor={(item) => item.id} renderItem={({ item }) => ( <View style={styles.listItem}> <Text style={styles.itemText}>{item.title}</Text> </View> )} /> </View> ); }; const styles = StyleSheet.create({ container: { flex: 1, padding: 20, backgroundColor: '#fff', }, title: { fontSize: 24, fontWeight: 'bold', marginBottom: 20, }, listItem: { paddingVertical: 15, borderBottomWidth: 1, borderBottomColor: '#eee', }, itemText: { fontSize: 18, }, }); export default ListScreen;
Quick Tips for Your Setup
- If using React Navigation v5+, switch to
createDrawerNavigatorandcreateStackNavigator(the API syntax is different but more flexible). - For VR, use libraries like
react-native-vror Expo's VR modules—follow a similar structure to the AR example. - Don't forget to request permissions for camera/motion sensors in your app's manifest or Expo config.
内容的提问来源于stack exchange,提问作者Muhammad Saad Ansari

