I have used 'react-navigation-material-bottom-tabs' for bottom tab navigation's which is working perfectly fine in android with ripple effect on tab click but ripple effect not working in ios ,
import * as React from 'react';
import Screen1 from './Screen1';
import Screen2 from './Screen2';
import { createAppContainer } from 'react-navigation';
import { createMaterialBottomTabNavigator } from 'react-navigation-material-bottom-tabs'; // <- notice where we import createMaterialBottomTabNavigator from
import { MaterialIcons } from '#expo/vector-icons';
const tabBarIcon = name => ({ tintColor }) => (
<MaterialIcons
style={{ backgroundColor: 'transparent' }}
name={name}
color={tintColor}
size={24}
/>
);
const screens = {
Screen1: {
screen: Screen1,
navigationOptions: {
tabBarIcon: tabBarIcon('photo-album'),
tabBarColor: 'blue' // <- set this to the color you want
}
},
Screen2: {
screen: Screen2,
navigationOptions: {
tabBarIcon: tabBarIcon('favorite'),
tabBarColor: 'green' // <- set this to the color you want
}
}
};
const config = {
headerMode: 'none',
initialRouteName: 'Screen1',
shifting: true, // <- notice this has been set to true
activeColor: 'white',
inactiveColor: 'black'
};
const MainNavigator = createMaterialBottomTabNavigator(screens, config);
export default createAppContainer(MainNavigator);
dependencies from package.json:
"dependencies": {
"react": "16.8.6",
"react-native": "0.60.4",
"react-native-gesture-handler": "^1.3.0",
"react-native-paper": "^2.16.0",
"react-native-svg": "^9.6.2",
"react-native-svg-icon": "^0.8.1",
"react-native-svg-uri": "^1.2.3",
"react-native-vector-icons": "^6.6.0",
"react-navigation": "^3.11.1",
"react-navigation-material-bottom-tabs": "^1.0.0"
}
Looking at your dependencies it looks like you haven't followed the instructions for installing react-navigation completely.
It would seem that you haven't installed react-native-reanimated it would make sense to install this as it is required for react-navigation.
You can install it as follows:
yarn add react-native-reanimated
or with npm
npm install react-native-reanimated
As you are using a version of react-native greater than 0.60.0 you should be able to rely on the automatic linking. However you may need to reinstall the pods. You can do this by opening a terminal at the root of your project and running the following commands.
$ cd ios
$ pod install
$ cd ..
Related
I want to use the ZegoCloudUIkit for voice call so after setting up my project, I imported the ZegoCloudUIKit and applied it to my existing code. I runned it and was getting errors.
first error message:
Error: Looks like you have nested a 'NavigationContainer' inside another. Normally you need only one container at the root of the app, so this was probably an error. If this was intentional, pass 'independent={true}' explicitly. Note that this will make the child navigators disconnected from the parent and you won't be able to navigate between them.
so I commentted the navigationContainer Component that was nested to the ZegoUIkit component and I got a different error but the console did not through the error instead from the mobile app.
secode error message:
this is my App.tsx file
import React, {useEffect, useState} from 'react';
import {StyleSheet, View} from 'react-native';
import RNBootSplash from 'react-native-bootsplash';
import {toast, Toasts} from '#backpackapp-io/react-native-toast';
import {SafeAreaProvider} from 'react-native-safe-area-context';
import axios from 'axios';
import AsyncStorage from '#react-native-async-storage/async-storage';
import {useDispatch, useSelector} from 'react-redux';
import {
ZegoUIKitPrebuiltCallWithInvitation,
ZegoInvitationType,
ONE_ON_ONE_VIDEO_CALL_CONFIG,
ONE_ON_ONE_VOICE_CALL_CONFIG,
GROUP_VIDEO_CALL_CONFIG,
GROUP_VOICE_CALL_CONFIG,
} from '#zegocloud/zego-uikit-prebuilt-call-rn';
import ZegoUIKitSignalingPlugin from '#zegocloud/zego-uikit-signaling-plugin-rn';
import {zego_appid, zego_appkey} from '#env';
import Main from './src/Main';
import {GestureHandlerRootView} from 'react-native-gesture-handler';
import {returnListOfProviders} from './src/redux/provider/listProvider';
import {provider} from './src/apis/endpoints';
import {RootState} from './src/types/redux.type';
import whichSignedUser from './src/utils/whichSignedUser';
import IClientData from './src/interfaces/clientData';
import IProviderData from './src/interfaces/providerData';
import {
NavigationContainer,
useNavigation,
useNavigationContainerRef,
} from '#react-navigation/native';
import {isSigned} from './src/redux/auth/isSigned';
import ActivityLoader from './src/components/widgets/ActivityLoader';
import {INavigateProps} from './src/interfaces';
import {Text} from 'react-native-animatable';
const App = () => {
const dispatch = useDispatch();
React.useEffect(() => {
const init = async () => {
try {
// const response = await listProvider();
const response = await axios.get(provider);
await AsyncStorage.setItem(
'list_provider',
JSON.stringify(response.data)
);
dispatch(
returnListOfProviders(
JSON.parse(await AsyncStorage.getItem('list_provider'))
)
);
} catch (error) {
if (error.message === 'Network Error') {
toast('Network error!');
} else if (error.response) {
// Request made but the server responded with an error
toast('Ouch... Something went wrong.');
} else if (error.request) {
// Request made but no response is received from the server.
toast('Request exception: We are sorry for this!');
} else {
// Error occured while setting up the request
toast('An error occured!');
}
}
};
init().finally(async () => {
await RNBootSplash.hide({fade: true});
});
}, [dispatch]);
return (
<SafeAreaProvider>
<GestureHandlerRootView style={styles.container}>
<ZegoUIKitPrebuiltCallWithInvitation
independent
appSign={zego_appkey}
appID={zego_appid}
userID={'ALi'}
callID={'ALi'}
userName={'ALi'}
// callID={userData?.id}
// userID={userData?.phone_number} // userID can be something like a phone number or the user id on your own user system.
// userName={`${userData?.first_name} ${userData?.last_name}`}
ringtoneConfig={{
incomingCallFileName: 'zego_incoming.mp3',
outgoingCallFileName: 'zego_outgoing.mp3',
}}
requireConfig={(data: any) => {
const config =
data.invitees.length > 1
? ZegoInvitationType.videoCall === data.type
? GROUP_VIDEO_CALL_CONFIG
: GROUP_VOICE_CALL_CONFIG
: ZegoInvitationType.videoCall === data.type
? ONE_ON_ONE_VIDEO_CALL_CONFIG
: ONE_ON_ONE_VOICE_CALL_CONFIG;
return config;
}}
// config={{
// ...ONE_ON_ONE_VOICE_CALL_CONFIG,
// onOnlySelfInRoom: () => {
// navigate('drawer_nav');
// },
// onHangUp: () => {
// navigate('drawer_nav');
// },
// }}
plugins={[ZegoUIKitSignalingPlugin]} // The signaling plug-in used for call invitation must be set here.
>
{/* <NavigationContainer> */}
<Main />
<Toasts />
{/* </NavigationContainer> */}
</ZegoUIKitPrebuiltCallWithInvitation>
</GestureHandlerRootView>
</SafeAreaProvider>
);
};
const styles = StyleSheet.create({
container: {flex: 1},
});
export default App;
while these are the project dependencies:
"dependencies": {
"#backpackapp-io/react-native-toast": "^0.8.0",
"#react-native-async-storage/async-storage": "^1.17.10",
"#react-native-community/picker": "^1.8.1",
"#react-navigation/bottom-tabs": "^6.3.3",
"#react-navigation/drawer": "^6.4.4",
"#react-navigation/material-top-tabs": "^6.2.4",
"#react-navigation/native": "^6.1.2",
"#react-navigation/native-stack": "^6.9.8",
"#reduxjs/toolkit": "^1.8.6",
"#types/react-native-vector-icons": "^6.4.12",
"#zegocloud/zego-uikit-prebuilt-call-rn": "^1.3.1",
"#zegocloud/zego-uikit-rn": "^1.4.10",
"#zegocloud/zego-uikit-signaling-plugin-rn": "^1.0.4",
"axios": "0.26.0",
"react": "18.1.0",
"react-delegate-component": "^1.0.0",
"react-native": "0.70.0",
"react-native-animatable": "^1.3.3",
"react-native-bootsplash": "^4.3.2",
"react-native-calendars": "^1.1289.0",
"react-native-date-picker": "^4.2.5",
"react-native-document-picker": "^8.1.1",
"react-native-dotenv": "^3.4.2",
"react-native-gesture-handler": "^2.8.0",
"react-native-image-picker": "^4.10.1",
"react-native-kommunicate-chat": "^1.6.8",
"react-native-pager-view": "^6.0.2",
"react-native-push-notification-popup": "^1.6.1",
"react-native-quick-base64": "^2.0.5",
"react-native-reanimated": "^2.10.0",
"react-native-safe-area-context": "^4.4.1",
"react-native-screens": "^3.18.2",
"react-native-select-dropdown": "^2.0.4",
"react-native-sound": "^0.11.2",
"react-native-tab-view": "^3.1.1",
"react-native-vector-icons": "^9.2.0",
"react-redux": "^8.0.4",
"zego-express-engine-reactnative": "^3.1.2",
"zego-zim-react-native": "^2.5.0"
},
other info:
info Fetching system and libraries information...
System:
OS: Linux 5.15 Zorin OS 16.2
CPU: (4) x64 Intel(R) Core(TM) i5-7200U CPU # 2.50GHz
Memory: 3.45 GB / 7.53 GB
Shell: 5.8 - /bin/zsh
Binaries:
Node: 16.18.1 - /tmp/yarn--1673425542734-0.8217341778464808/node
Yarn: 1.22.19 - /tmp/yarn--1673425542734-0.8217341778464808/yarn
npm: 9.2.0 - ~/.nvm/versions/node/v16.18.1/bin/npm
Watchman: Not Found
SDKs:
Android SDK: Not Found
IDEs:
Android Studio: Not Found
Languages:
Java: 17.0.5 - /usr/bin/javac
npmPackages:
#react-native-community/cli: Not Found
react: 18.1.0 => 18.1.0
react-native: 0.70.0 => 0.70.0
npmGlobalPackages:
*react-native*: Not Found
I am trying to achieve something similar to the article here.
In my case I want to have a one_on_one_voice_call where a caller can invite the other person on a call.
"react-native": "^0.57.0",
"react-navigation": "^3.0.0",
"react-navigation-redux-helpers": "^2.0.7",
"react-redux": "^5.0.6",
"redux": "^4.0.0",
"redux-thunk": "^2.3.0",
"reduxsauce": "0.7.0",
"react-native-gesture-handler": "^1.0.9",
Updating react-navigation to 3.0.0 in my React-Native app. I have followed the official docs here React Navigation and installed all the dependencies.
However cannot resolve this issue.
AppNavigation.js
const PrimaryNav = createStackNavigator({
HomeScreen: {
screen: MainTabNav,
}, {
mode: 'modal',
headerMode: 'none',
initialRouteName: 'HomeScreen',
navigationOptions: {
headerStyle: styles.header,
},
});
export default createAppContainer(PrimaryNav);
ReduxNavigation.js
import AppNavigation from './AppNavigation';
import { reduxifyNavigator, createReactNavigationReduxMiddleware } from
'react-navigation-redux-helpers';
createReactNavigationReduxMiddleware(
'root',
state => state.nav,
);
const ReduxAppNavigator = reduxifyNavigator(AppNavigation, 'root');
render() {
const { dispatch, nav } = this.props;
<ReduxAppNavigator state={nav} dispatch={dispatch} />
}
const mapStateToProps = state => ({ nav: state.nav });
export default connect(mapStateToProps)(ReduxNavigation);
navigation.js
import { Keyboard } from 'react-native';
import AppNavigation from '../navigation/AppNavigation';
export default (state, action) => {
Keyboard.dismiss();
const newState = AppNavigation.router.getStateForAction(action, state);
return newState || state;
};
CreateStore.js
import { createStore, applyMiddleware, compose } from 'redux';
import reduxThunkMiddleware from 'redux-thunk';
import { createReactNavigationReduxMiddleware } from 'react-navigation-redux-
helpers';
import screenTrackingMiddleware from './screenTrackingMiddleware';
export default (rootReducer) => {
const middleware = [];
const enhancers = [];
const navigationMiddleware = createReactNavigationReduxMiddleware(
'root',
state => state.nav,
);
middleware.push(screenTrackingMiddleware);
middleware.push(navigationMiddleware);
middleware.push(reduxThunkMiddleware);
enhancers.push(applyMiddleware(...middleware));
const store = createStore(rootReducer, compose(...enhancers));
return {
store,
};
};
RootContainer.js
import ReduxNavigation from 'navigation/ReduxNavigation';
export default class RootContainer extends Component {
render() {
return (
<View style={styles.applicationView}>
<StatusBar barStyle="light-content" />
<ReduxNavigation />
</View>
);
}
}
This happens because you didn't link react-native-gesture-handler
Just type react-native link in your project dir.
And run again react-native run-android
Solved the issue by adding this plugin to .babelrc file.
[
"#babel/plugin-transform-flow-strip-types",
]
I am trying to integrate redux with react-navigation using react-navigation-redux-helpers in react-native with expo. However, though I followed the documentations I get the following error.
This navigator has both navigation and container props, so it is unclear if it should own its own state. Remove props: "nav" if the navigator should get its state from the navigation prop. If the navigator should maintain its own state, do not pass a navigation prop.
Following is my code related to the redux and react-navigation implementation.
AppNavigator.js
import React from 'react';
import {createSwitchNavigator, createStackNavigator} from 'react-navigation';
import {connect} from 'react-redux';
import {reduxifyNavigator,createReactNavigationReduxMiddleware} from "react-navigation-redux-helpers";
import MainTabNavigator from './MainTabNavigator';
export const AuthStack = createStackNavigator(
{
Main: MainTabNavigator,
},
{
headerMode: 'none'
}
);
export const AppNavigator = createSwitchNavigator(
{
Auth: AuthStack,
},
{
headerMode: 'none',
initialRouteName: 'Auth',
}
);
export const NavMiddleware = createReactNavigationReduxMiddleware(
"root",
state => state.nav,
);
const addListener = reduxifyNavigator(AppNavigator, 'root');
const mapStateToProps = state => ({
nav: state.nav,
});
export const AppWithNavigationState = connect(mapStateToProps)(addListener);
App.js
import React from 'react';
import {Platform, StatusBar, StyleSheet, View} from 'react-native';
import {AppLoading, Asset, Font, Icon} from 'expo';
import {AppWithNavigationState} from './navigation/AppNavigator';
import {applyMiddleware, createStore} from "redux";
import AppReducer from './reducers/AppReducer'
import {Provider} from "react-redux";
import {NavMiddleware} from './navigation/AppNavigator'
const store = createStore(AppReducer,applyMiddleware(NavMiddleware));
export default class App extends React.Component {
state = {
isLoadingComplete: false,
};
render() {
if (!this.state.isLoadingComplete && !this.props.skipLoadingScreen) {
return (
<AppLoading
startAsync={this._loadResourcesAsync}
onError={this._handleLoadingError}
onFinish={this._handleFinishLoading}
/>
);
} else {
return (
<View style={styles.container}>
{Platform.OS === 'ios' && <StatusBar barStyle="default" />}
<Provider store={store}>
<AppWithNavigationState/>
</Provider>
</View>
);
}
}
_loadResourcesAsync = async () => {
return Promise.all([
Asset.loadAsync([
require('./assets/images/robot-dev.png'),
require('./assets/images/robot-prod.png'),
]),
Font.loadAsync({
// This is the font that we are using for our tab bar
...Icon.Ionicons.font,
// We include SpaceMono because we use it in HomeScreen.js. Feel free
// to remove this if you are not using it in your app
'space-mono': require('./assets/fonts/SpaceMono-Regular.ttf'),
}),
]);
};
_handleLoadingError = error => {
// In this case, you might want to report the error to your error
// reporting service, for example Sentry
console.warn(error);
};
_handleFinishLoading = () => {
this.setState({ isLoadingComplete: true });
};
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
},
});
navReducer.js
import {AppNavigator} from '../navigation/AppNavigator';
const router = AppNavigator.router;
const mainNavAction = router.getActionForPathAndParams('Auth');
const initialNavState = router.getStateForAction(mainNavAction);
const NavigationReducer = (state = initialNavState, action) => {
console.log('routes', router);
return router.getStateForAction(action, state) || state;
};
export default NavigationReducer;
AppReducer.js
"use strict";
import {VendorReducer} from './vendorReducer';
import {combineReducers} from "redux";
import NavigationReducer from "./navReducer";
const AppReducer = combineReducers({
nav:NavigationReducer,
vendor: VendorReducer,
});
export default AppReducer;
Following is my package.json.
{
"name": "my-new-project",
"main": "node_modules/expo/AppEntry.js",
"private": true,
"scripts": {
"start": "expo start",
"android": "expo start --android",
"ios": "expo start --ios",
"eject": "expo eject",
"test": "node ./node_modules/jest/bin/jest.js --watchAll"
},
"jest": {
"preset": "jest-expo"
},
"dependencies": {
"#expo/samples": "2.1.1",
"expo": "^30.0.1",
"react": "16.3.1",
"react-native": "https://github.com/expo/react-native/archive/sdk-30.0.0.tar.gz",
"react-navigation": "2.16.0",
"react-navigation-redux-helpers": "2.0.6",
"react-redux": "5.0.7",
"redux": "4.0.0",
"redux-logger": "3.0.6",
"redux-thunk": "2.3.0"
},
"devDependencies": {
"jest-expo": "30.0.0",
"redux-devtools": "3.4.1"
}
}
I hope someone could help me to get through this. Thanks in-advance.
This was also my mistake! solved it by:
const mapStateToProps = state => ({
state: state.nav,
});
pay attention to state: state.nav.
If you need, i can post my whole redux integration with the navigation that work for me.
Dependencies version:
"dependencies": {
"react": "16.3.1",
"react-native": "~0.55.2",
"react-navigation": "^2.0.1",
}
I use react-navigation to navigate my screen, i create two screen and a drawer
Router.js:
import { createStackNavigator, createDrawerNavigator } from 'react-navigation';
import MainActivity from './components/MainActivity';
import ThisWeek from './components/ThisWeek';
import DrawerPanel from './components/DrawerPanel';
const Stack = createStackNavigator({
MainActivity: {
screen: MainActivity,
navigationOptions: {
title: 'Welcome',
headerStyle: {
backgroundColor: '#81A3A7',
elevation: null
}
}
},
ThisWeek: {
screen: ThisWeek
}
},
{
initialRouteName: 'MainActivity'
}
);
const Router = createDrawerNavigator({
FirstScreen: {
screen: Stack
}
},
{
contentComponent: DrawerPanel,
drawerWidth: 200
});
export default Router;
In my DrawerPanel.js i can click the two button navigate to the screen, but when i try to use this.props.navigation.closeDrawer(); that shows an error _this2.props.navigation.closeDrawer is not a function.
So i try to console.log(this.props);,i can see openDrawer and closeDrawer under navigation
Here is my DrawerPanel.js:
import React, { Component } from 'react';
import { ScrollView, FlatList, Text } from 'react-native';
import { View } from 'react-native-animatable';
import { List, Button } from 'react-native-elements';
class DrawerPanel extends Component {
render() {
console.log(this.props);
return (
<ScrollView style={{ backgroundColor: '#81A3A7' }}>
<Button
onPress={() => {
this.props.navigation.actions.closeDrawer();
this.props.navigation.navigate('MainActivity');
}}
backgroundColor={'#81A3A7'}
containerViewStyle={{ width: '100%', marginLeft: -61 }}
title='Main page'
/>
<Button
onPress={() => this.props.navigation.navigate('ThisWeek')}
backgroundColor={'#81A3A7'}
containerViewStyle={{ width: '100%', marginLeft: -46 }}
title='This weel'
/>
</ScrollView>
);
}
}
export default DrawerPanel;
I can't figure it out why i can use this.props.navigation.navigate(); to another screen not allow to use this.props.navigation.closeDrawer();
I try make a change to use this.props.navigation.actions.closeDrawer(); the error will show Cannot read property 'closeDrawer' of undefined.
What step i make it wrong ? Any help would be appreciated. Thanks in advance.
Try this
import { DrawerActions } from 'react-navigation';
this.props.navigation.dispatch(DrawerActions.closeDrawer());
this.props.navigation.dispatch(DrawerActions.openDrawer());
You are using both StackNavigator and DrawrNavigator so that the way to use them is different a little bit.
Keep in mind we have two version for react-navigation (v1 and v2) for now so that you should read the documentation carefully.
Please try using this:
Close drawer
this.props.navigation.navigate('DrawerClose'); // for version 1
this.props.navigation.openDrawer(); // for version 2
Open drawer:
this.props.navigation.navigate('DrawerOpen'); // for version 1
this.props.navigation.closeDrawer(); // for version 2
Be careful for reference any bugs fix for this libraries on the internet which you have to know which version is using in.
Note that the order of nesting - if the stack navigator is not inside of the drawer, it will not have the openDrawer function.
I guess it will work for you in this case.
Cheer!
In your DrawerPanel file. You did not use the constructor. Hence, your component's props did not know about the navigation props that the DrawerNavigator passed in. Try putting this before your render function in the component.
constructor(props){
super(props);
}
This way you will no longer need to use dispatch(), but instead use openDrawer() and closeDrawer().
I'm developing a new app with RN and using TabNavigator from react-navigation library, the most basic example of TabNavigator only showing first Tab. I've read somewhere that it could be a bug and could be solved by downgrading react-navigation to 1.0.3 but it didn't work for me. How to solve it?
tab1
tab2
app.js
import React, { Component } from 'react';
import Dashboard from './screens/Dashboard';
import Profile from './screens/Profile';
// import {I18nManager} from 'react-native';
// import { Container, Header, Content, Footer, FooterTab, Button, Icon, Text, Badge, Tab, Tabs } from 'native-base';
import { TabNavigator, TabBarBottom } from 'react-navigation';
import Ionicons from 'react-native-vector-icons/Ionicons';
export default TabNavigator({
home: { screen: Dashboard },
profile: { screen: Profile },
nav: { screen: Dashboard },
},
{
navigationOptions: ({ navigation }) => ({
tabBarIcon: ({ focused, tintColor }) => {
const { routeName } = navigation.state;
let iconName;
if (routeName === 'home') {
iconName = `ios-pulse${focused ? '' : '-outline'}`;
} else if (routeName === 'profile') {
iconName = `ios-person${focused ? '' : '-outline'}`;
}
// You can return any component that you like here! We usually use an
// icon component from react-native-vector-icons
return <Ionicons name={iconName} size={25} color={tintColor} />;
},
}),
tabBarOptions: {
activeTintColor: 'blue',
inactiveTintColor: 'gray',
},
tabBarComponent: TabBarBottom,
lazy: false,
tabBarPosition: 'bottom',
animationEnabled: false,
swipeEnabled: false,
}
);
Dashboard.js
import React, { Component } from 'react';
import { TouchableOpacity,
Title,
Subtitle,
Tile,
Divider,
ImageBackground,
Card,
Image,
View,
Caption,
GridRow,
ListView,
Screen
} from '#shoutem/ui';
// import I18n from 'react-native-i18n';
// import {I18nManager} from 'react-native';
// I18nManager.forceRTL(true);
export default class Dashboard extends Component {
constructor(props) {
super(props);
this.renderRow = this.renderRow.bind(this);
this.state = {
restaurants: [
{
'name': 'برنامه ۳۰ روزه هوازی',
'address': 'چربی سوزی | کاهش وزن',
'image': { 'url': 'https://shoutem.github.io/static/getting-started/restaurant-1.jpg' },
},
{
'name': 'تمرین سینه',
'address': 'افزایش قدرت و حجم عضلات سینه و فرم دهی به آن',
'image': { 'url': 'https://shoutem.github.io/static/getting-started/restaurant-2.jpg' },
},
{
'name': 'تمرین شکم',
'address': 'حاضرید که عضلات شکمتان را ورزیده و تکه کنید؟ حرکاتی که در زیر آمده، راهنمایی است که همیشه برای شما کافی و مفید خواهد بود.',
'image': { 'url': 'https://shoutem.github.io/static/getting-started/restaurant-3.jpg' },
},
{
'name': 'تمرین سینه',
'address': 'افزایش قدرت و حجم عضلات سینه و فرم دهی به آن',
'image': { 'url': 'https://shoutem.github.io/static/getting-started/restaurant-2.jpg' },
},
{
'name': 'تمرین شکم',
'address': 'حاضرید که عضلات شکمتان را ورزیده و تکه کنید؟ حرکاتی که در زیر آمده، راهنمایی است که همیشه برای شما کافی و مفید خواهد بود.',
'image': { 'url': 'https://shoutem.github.io/static/getting-started/restaurant-3.jpg' },
},
{
'name': 'تمرین ران پا',
'address': 'این یک تست است.',
'image': { 'url': 'https://shoutem.github.io/static/getting-started/restaurant-2.jpg' },
},
],
};
}
renderRow(rowData, sectionId, index) {
// rowData contains grouped data for one row,
// so we need to remap it into cells and pass to GridRow
if (index === '0') {
return (
<TouchableOpacity key={index}>
<ImageBackground
styleName="large"
source={{ uri: rowData[0].image.url }}
>
<Tile>
<Title styleName="md-gutter-bottom">{rowData[0].name}</Title>
<Subtitle styleName="sm-gutter-horizontal">{rowData[0].address}</Subtitle>
</Tile>
</ImageBackground>
<Divider styleName="line" />
</TouchableOpacity>
);
}
const cellViews = rowData.map((restaurant, id) => {
return (
<TouchableOpacity key={id} styleName="flexible">
<Card styleName="flexible">
<Image
styleName="medium-wide"
source={{ uri: restaurant.image.url }}
/>
<View styleName="content">
<Subtitle numberOfLines={3}>{restaurant.name}</Subtitle>
<View styleName="horizontal">
<Caption styleName="collapsible" numberOfLines={2}>{restaurant.address}</Caption>
</View>
</View>
</Card>
</TouchableOpacity>
);
});
return (
<GridRow columns={2}>
{cellViews}
</GridRow>
);
}
render() {
const restaurants = this.state.restaurants;
// Group the restaurants into rows with 2 columns, except for the
// first restaurant. The first restaurant is treated as a featured restaurant
let isFirstArticle = true;
const groupedData = GridRow.groupByRows(restaurants, 2, () => {
if (isFirstArticle) {
isFirstArticle = false;
return 2;
}
return 1;
});
return (
<ListView
data={groupedData}
renderRow={this.renderRow}
/>
);
}
}
Profile.js
import React, { Component } from 'react';
import { Container, Header, Content, Form, Item, Input, Label } from 'native-base';
// import I18n from 'react-native-i18n';
// import {I18nManager} from 'react-native';
// I18nManager.forceRTL(true);
export default class Profile extends Component {
render() {
return (
<Container>
<Header />
<Content>
<Form>
<Item floatingLabel>
<Label>نام</Label>
<Input />
</Item>
<Item floatingLabel last>
<Label>قد (سانتیمتر)</Label>
<Input />
</Item>
</Form>
</Content>
</Container>
);
}
}
package.json
"dependencies": {
"#shoutem/ui": "^0.23.4",
"native-base": "^2.4.2",
"react": "16.3.1",
"react-native": "0.55.3",
"react-native-vector-icons": "^4.6.0",
"react-navigation": "^1.0.3"
},
"devDependencies": {
"babel-jest": "22.4.3",
"babel-preset-react-native": "4.0.0",
"eslint": "^4.19.1",
"eslint-plugin-react": "^7.7.0",
"jest": "22.4.3",
"react-test-renderer": "16.3.1"
},
"jest": {
"preset": "react-native"
}
I've already tried latest version of react-navigation so its downgraded version you see in package.json
I've found solution to this, and I'm going to be as specific as I can for all the people out there that might face this!
First of all it's a problem with I18nManager.forceRTL(true);
the moment you use this line of code anywhere on your react-native code that its screen gonna get rendered, and on 2nd reload, the app the layout is being change to RTL, and it does not change even if you comment that line! You'll have to use I18nManager.forceRTL(false); and reload a couple of times to get back to normal ltr setup.
The thing is... some of us really need that RTL layout change like I thought I did! Well guess what react-navigation does not respect that, at least for now and in the TabNabigator dept.
So to sum it all up: RTL layout on RN will break your react-navigation's Tab Navigation! (as of the current version you can see in the packages.json above) The issue makes only the first that visible and for the others a bland tab shows, if you turn on the animation or swipe other tabs will show but tabs behave in a weird way, meaning the last tab is active when the first one is active and vice versa... middle tabs are never focused by the way.
So you should know you can't use tabbed navigation with RTL layout. I'll update this answer after this issue got a fix!
I have run it using react-native run-ios, and all the tabs display a different screen. If you are referring to the fact that the nav tab does not change when you click on it whilst on the home tab, both the home and nav tabs are using the Dashboard screen.
The following is my package.json file for this project:
{
"name": "a",
"version": "0.0.1",
"private": true,
"scripts": {
"start": "node node_modules/react-native/local-cli/cli.js start",
"test": "jest"
},
"dependencies": {
"react-native-code-push": "1.15.0-beta",
"#babel/core": "^7.0.0-beta.40",
"#shoutem/ui": "^0.23.4",
"eslint": "^3.19.0",
"native-base": "^2.4.2",
"react": "16.3.1",
"react-native": "0.55.3",
"react-native-vector-icons": "^4.6.0",
"react-navigation": "^1.5.11"
},
"devDependencies": {
"babel-jest": "22.4.3",
"babel-preset-react-native": "4.0.0",
"jest": "22.4.3",
"react-test-renderer": "16.3.1"
},
"jest": {
"preset": "react-native"
}
}