I'm using react-native-router-flux in my app and want to pass in paths to png images for my TabIcon components. I know I could just make a different tab icon component for each tab, but these icons would be exactly the same except for the image source and I want to find a DRY way to accomplish my goal. Where in my scenes can I pass in the image path?
Here is my TabIcon component:
const TabIcon = ({ selected, title, image }) => {
const tabStyle = selected ? styles.selected : styles.unselected
return (
<View style={tabStyle}>
<Image
style={{height: 35, width: 35}}
source={require(image)}
/>
</View>
)
}
My scenes:
const Scenes = Actions.create(
<Scene key='root'>
<Scene key='tabbar' tabs={true} tabBarStyle={styles.tabBarStyle}>
<Scene key='tab1' title='Feed' icon={TabIcon}>
<Scene
key='Feed'
component={Feed}
title='Feed'
initial={true}
/>
</Scene>
<Scene key='tab2' title='Create' icon={TabIcon}>
<Scene
key='Create'
component={Create}
title='Create'
/>
</Scene>
<Scene key='tab3' title='Leaderboard' icon={TabIcon}>
<Scene
key='leaderboard'
component={Leaderboard}
title='Leaderboard'
/>
</Scene>
</Scene>
</Scene>
)
EDIT
I have tried passing in the image like so
const Scenes = Actions.create(
<Scene key='root'>
<Scene key='tabbar' tabs={true} tabBarStyle={styles.tabBarStyle}>
//HERE
<Scene key='tab1' title='Feed' icon={TabIcon} image={'../images/feed.png'}>
<Scene
key='matchupsFeed'
component={MatchupsFeed}
title='Feed'
initial={true}
/>
</Scene>
...
...
...
Within my TabIcon component if I console.log(image) it prints out "../images/feed.png" but I get this error in the simulator:
Unknown named module: '../images/feed.png'
After taking a look at this SO question, I figured it out:
const TabIcon = ({ selected, title, image }) => {
const selectColor = selected ? '#ED1B25' : '#FFF'
return (
<View style={[styles.tabStyle, {borderBottomColor: selectColor}]}>
<Image
style={{height: 35, width: 35}}
// Change HERE
source={image}
/>
</View>
)
}
Scenes
const Scenes = Actions.create(
<Scene key='root'>
<Scene key='tabbar' tabs={true} tabBarStyle={styles.tabBarStyle}>
//Change HERE
<Scene key='tab1' title='Feed' icon={TabIcon} image={require('../images/feed.png')}>
Related
I am new in react native and I have problem.
In my application a have 3 scenes and custom navbar. I need diffrent image on different scene. If I only change background it's work perfect, but I need more its mean image
//router.js
<Scene key="root" navBar={Navbar} drawer contentComponent={Drawer}>
<Scene key="home" component={Home} initial={true} hideNavBar={true} />
<Scene key="op" ref="Op" component={Op}
navigationBarStyle = {styles.sceneOp}
/>
<Scene key="about" component={About}
navigationBarStyle = {styles.sceneAbout}
/>
</Scene>
...
const styles = StyleSheet.create({
sceneOp: {
backgroundColor: 'grey',
},
sceneAbout: {
backgroundColor: 'yellow',
}
});
//navbar.js - in this file, I need that my dynamicLogo was props like navigationBarStyle. How to do this?
render() {
let dynamicLogo = navStyle.assets.img;
return (
<View style={styles.outerContainer, this.props.navigationBarStyle}>
<View style={styles.innerContainer}>
<TouchableOpacity
onPress={() => {
Actions.drawerOpen();
}}
style={styles.sideElementContainer}
>
<Image style={styles.burger} source={require('../assets/burger-icon.png')} />
</TouchableOpacity>
<View style={styles.logoContainer}>
<Image style={styles.logo} source={dynamicLogo} />
</View>
<View style={styles.sideElementContainer} />
</View>
</View>
);
}
I did it by using renderTitle
//Routers.js
<Scene key="root" navBar={Navbar} drawer contentComponent={Drawer}>
<Scene key="home" component={Home} initial={true} hideNavBar={true} />
<Scene key="op" ref="Op" component={Op}
navigationBarStyle = {styles.sceneOp}
renderTitle={navImage.imgExto}
/>
<Scene key="about" component={About}
navigationBarStyle = {styles.sceneAbout}
renderTitle={navImage.imgMe}
/>
</Scene>
...
const navImage = {
imgExto: require('./assets/e-logo.png'),
imgMe: require('./assets/m-logo.png'),
};
I'm making simple application using react-native, and I am Using react-native-router-flux.
I want to change header component from 'chat' to 'Username' when i'm in nested screen. I tried several ways but I don't know where to put the header component code.
Code for TabBar
<Router titleStyle={styles.navTitle} >
<Scene key="root">
<Scene title="Chat" initial key="root" tabBarPosition='top' tabs tabBarStyle={{ top: 0, backgroundColor: '#ddd' }} tabBarIconContainerStyle={{ borderColor: '#000', borderWidth: 1}} initial>
<Scene key="first" title="First" icon={TabIcon}>
<Scene key="scarlet" component={BlueScreen} hideNavBar initial />
</Scene>
<Scene key="second" title="Second" icon={TabIcon}>
<Scene key="scarlet2" component={GrayScreen} hideNavBar initial />
</Scene>
<Scene key="third" title="Third" icon={TabIcon}>
<Scene key="scarlet3" component={ScarletScreen} hideNavBar initial />
<Scene key="root" component={SecondScene} hideNavBar title="Username" />
</Scene>
</Scene>
</Scene>
when I'm in SecondScene I want my header change from Chat to Username
You can add this code in the Component where you switch the tab and want username as header.
Actions.refresh({ title: 'Username' }).
you can add this line of code as per your Apps flow.
If you are switching to chat you can add
Actions.refresh({ title: 'chat' }).
Hope it helps !
You can change navigation title anytime. For your use when you got the username just run the following code.
this.props.navigation.setParams({
title: "YOUR_USER_NAME",
});
If you get the user name when navigating to current scene it's better you change the title in componentWillMount.
componentWillMount() {
this.props.navigation.setParams({
title: "YOUR_USER_NAME",
});
}
I am using react-native with react-native-router-flux and I want to use both Drawer sidemenu and also tabbar. But it only shows the one I put on top. My code is below. If I put Drawer first then it only shows Drawer.
import React from 'react';
import { StyleSheet, Text, View, Image } from 'react-native';
import { Router, Scene, Stack, Tabs, Drawer } from 'react-native-router-flux';
import ScarletScreen from './component/ScarletScreen';
import ProfileScreen from './component/ProfileScreen';
import WhiteScreen from './component/WhiteScreen';
import BlackScreen from './component/BlackScreen';
import SideMenu from './component/SideMenu';
const TabIcon = ({ selected, title }) => { return (
<Text style={{color: selected ? 'red' :'black'}}>{title}</Text> ); }
export default class App extends React.Component { render() {
return (
<Router>
<Scene key="root" hideNavBar>
{/* Drawer and it's scenes */}
<Drawer key="drawer" drawerImage={require('./img/hamburger.png')} contentComponent={SideMenu}>
<Scene key="main">
<Scene
key="scarlet"
component={ScarletScreen}
title="Scarlet Screen"
initial
/>
<Scene
key="profile"
component={ProfileScreen}
title="Profile"
/>
<Scene
key="white"
component={WhiteScreen}
title="White Screen"
/>
<Scene
key="black"
component={BlackScreen}
title="Black Screen"
/>
</Scene>
</Drawer>
{/* Tab and it's scenes */}
<Tabs
key="tabbar"
tabBarStyle={{ backgroundColor: '#FFFFFF' }}
>
{/* Tab and it's scenes */}
<Scene key="osu" title="OSU" icon={TabIcon}>
<Scene
key="scarlet"
component={ScarletScreen}
title="Scarlet Screen"
/>
<Scene
key="white"
component={WhiteScreen}
title="White Screen"
/>
</Scene>
{/* Tab and it's scenes */}
<Scene key="um" title="UM" icon={TabIcon}>
<Scene
key="white"
component={WhiteScreen}
title="White"
/>
<Scene
key="black"
component={BlackScreen}
title="Black"
/>
</Scene>
</Tabs>
</Scene>
</Router>
); } }
If I put tabbar first, then it shows the tabbar only and the hamburger menu icon is gone.
{/* Tab and it's scenes */}
<Tabs
key="tabbar"
tabBarStyle={{ backgroundColor: '#FFFFFF' }}
>
{/* Tab and it's scenes */}
<Scene key="osu" title="OSU" icon={TabIcon}>
<Scene
key="scarlet"
component={ScarletScreen}
title="Scarlet Screen"
/>
<Scene
key="white"
component={WhiteScreen}
title="White Screen"
/>
</Scene>
{/* Tab and it's scenes */}
<Scene key="um" title="UM" icon={TabIcon}>
<Scene
key="white"
component={WhiteScreen}
title="White"
/>
<Scene
key="black"
component={BlackScreen}
title="Black"
/>
</Scene>
</Tabs>
{/* Drawer and it's scenes */}
<Drawer key="drawer" drawerImage={require('./img/hamburger.png')} contentComponent={SideMenu}>
<Scene key="main">
<Scene
key="scarlet"
component={ScarletScreen}
title="Scarlet Screen"
initial
/>
<Scene
key="profile"
component={ProfileScreen}
title="Profile"
/>
<Scene
key="white"
component={WhiteScreen}
title="White Screen"
/>
<Scene
key="black"
component={BlackScreen}
title="Black Screen"
/>
</Scene>
</Drawer>
I use create-react-native-app to create my react-native app
I word on react-native-router-flux and I have a problem ... I am reset my Stack navigation when I am changing of Tab navigation.
I try with backToInitial but I need to press two times on my tab for reset my stack ... I don't understand why.
My navigation :
-OSU
-Scarlet
-Gray
-VU
-Blue
-Black
So when I am on Blue and I press one time on OSU I when to access at Scarlet not gray
My code :
export default class App extends Component {
render() {
return (
<Router>
<Tabs
key="tabbar"
tabBarStyle={{ backgroundColor: '#FFFFFF' }}
backToInitial={true}
>
<Scene key="osu" title="OSU" icon={TabIcon} type='reset' backToInitial={true}>
<Scene
key="scarlet"
component={ScarletScreen}
title="Scarlet"
/>
<Scene
key="gray"
component={GrayScreen}
title="Gray"
/>
</Scene>
<Scene key="vu" title="VU" icon={TabIcon} backToInitial={true}>
<Scene
key="blue"
component={BlueScreen}
title="Blue"
/>
<Scene
key="black"
component={BlackScreen}
title="Black"
/>
</Scene>
</Tabs>
</Router>
);
}
}
I have my react component on my main index file or my main component I would like to pass a state change to that component but from a pure JS file/function not sure what's the best approach or correct way of doing this. I have tested it with redux but feels like an overkill especially since I need to pass loading progress.
it's basically loading overlay which needs to be called from the post api file.
Here is my code
Index
render() {
return (
<View style={styles.container}>
<Provider store={store}>
<ConnectedRouter>
<Scene key="root" hideNavBar hideTabBar>
<Scene key="public">
<Scene key="login" component={Login} initial={true} title={'Login'} />
<Scene key="ResetPassword" component={ResetPassword} title={'Reset Password'} />
</Scene>
<Scene key="tabBar" tabs lazy>
<Scene key="tab1" title="Home" tabBarLabel="Home" icon={HomeTabIcon}>
<Scene key='Home' component={Home} title='Home' initial={true} panHandlers={null}/>
<Scene key='Teams' component={Teams} title='Teams' initial={false} />
</Scene>
<Scene key="tab2" title="Photos" tabBarLabel="Photos" icon={PhotosTabIcon}>
<Scene key='Photos' component={Photos} title='Photos' back backTitle='Back' initial={false} />
<Scene key='SinglePhoto' component={SinglePhoto} title='Photo' back backTitle='Back' initial={false} />
<Scene key='PhotoUpload' component={PhotoUpload} title='Upload Photo' back backTitle='Back' initial={false} />
</Scene>
<Scene key="tab3" title="Site Diary" tabBarLabel="Site Diary" icon={SiteDiaryTabIcon}>
<Scene key='SiteDiary' component={SiteDiary} title='SiteDiary' initial={false} />
</Scene>
</Scene>
</Scene>
</ConnectedRouter>
</Provider>
<MessageBar/>
<LoadingOverlay isVisible={this.state.overlayIsVisible} progress={this.state.overlayProgress} indeterminate={this.state.indeterminate} />
</View>
);
}
API file
export const sync = (isConnected) => {
const offlineData = store.getState().newData;
console.log(offlineData);
// We have offline data
if(!_.isEmpty(offlineData.photos)){
console.log('We have offline data')
// We have a connection
if(isConnected) {
console.log('We have a connection')
// Loops thur the offline data and uploads it
//for (let i = 0; i < offlineData.length; i++) {
//}
}
}
};
Which is getting called from index via the following
// Connection function for offline / online
_handleConnectionChange = (isConnected) => {
// Updates the store with selected project
store.dispatch(connectionActionCreators.update(isConnected));
// Gets the offline data from the store
const hasOfflineData = store.getState().newData.hasData;
console.log(hasOfflineData);
if(hasOfflineData){
this.setState({
overlayIsVisible:true,
//overlayProgress:0,
});
}
// Syncs data
syncOffineData.sync(isConnected);
};