For my react-native application I implement navigations with react-native-router-flux. I have a Drawer menu which is accessible through several different pages. On IOS everything is fine. Whereas, not all but on some android devices redirecting links on the drawer menu does not work. Is there someone faced this problem before? And how did you solve it? I used react-native-router-flux on all pages of my application. So, I do not want to use another navigation component in Drawer menu.
Here is my drawer menu code.
import React, {Component} from 'react';
import {Actions} from 'react-native-router-flux';
import {Text,View,Container} from 'react-native';
import {Button,Icon} from 'native-base';
export default class SideBarContent extends Component{
constructor() {
super();
}
render()
{
const css = {
"Button": {color: '#E5DDCB',fontFamily: 'SourceSansPro-Regular'}
}
return(
<View style={{top: 80}} >
<Button transparent onPress={()=>Actions.ordersMain()}><Icon style={{color: "#FFF",margin: 10}} name="md-card"/><Text style={css.Button}>Order History</Text></Button>
<Button transparent onPress={()=>Actions.account()}><Icon style={{color: "#FFF",margin: 10}} name="md-person-add"/><Text style={css.Button}>Profile</Text></Button>
<Button transparent onPress={()=>Actions.addresses()}><Icon style={{color: "#FFF",margin: 10}} name="md-navigate"/><Text style={css.Button}>Addresses</Text></Button>
<Button transparent><Icon style={{color: "#FFF",margin: 10}} name="md-information-circle"/><Text style={css.Button}>Account</Text></Button>
<Button transparent onPress={()=>Actions.category()}><Icon style={{color: "#FFF",margin: 10}} name="md-archive"/><Text style={css.Button}>Categories</Text></Button>
</View>
);
}
}
Here is how I implement menu on pages.
return (
<Drawer
tapToClose={true}
open={false}
type="displace"
content={<SideBarContent />}
ref = {(ref) => this._drawer = ref}
openDrawerOffset={width/3}
closedDrawerOffset={0}
styles={drawerStyles}
tweenHandler={Drawer.tweenPresets.parallax}
elevation={0}
onClose={()=>this.onClose()}
>
<Container style={{backgroundColor: '#FFF'}}>
//....Page Code...
</Container>
</Drawer>
);
Here is image of my drawer.
Related
I'm learning how to build mobile applications with React Native and I'm following a React native course by Programming with Mosh. However, I ran into a problem where I can't get my program to allow me to swipe left to delete a list item. Swiping left should open up a red square.
I have tried reading the documentation, googling answers and watching youtube videos, but I have made 0 progress :(.
Here's my code for the ListItem component:
import React from 'react';
import {View, StyleSheet, Image, TouchableHighlight } from 'react-native';
import Swipeable from 'react-native-gesture-handler/Swipeable';
import colors from '../config/colors';
import AppText from './AppText';
function ListItem({title, subTitle, image, onPress, renderRightActions}) {
return (
<Swipeable renderRightActions={renderRightActions}>
<TouchableHighlight
underlayColor={colors.lightGrey}
onPress={onPress}>
<View style={styles.container}>
<Image style={styles.image} source={image} />
<View style={styles.textContainer}>
<AppText style={styles.title}>{title}</AppText>
<AppText style={styles.subTitle}>{subTitle}</AppText>
</View>
</View>
</TouchableHighlight>
</Swipeable>
);
}
and here is the code for when I actually use it:
import React from 'react';
import {StyleSheet, FlatList} from 'react-native';
import ListItem from '../components/ListItem';
import Screen from '../components/Screen';
import ListItemSeperator from '../components/ListItemSeperator';
import ListItemDeleteAction from '../components/ListItemDeleteAction';
function MessagesScreen(props) {
return (
<Screen>
<FlatList
data={messages}
keyExtractor={message => message.id.toString()}
renderItem={({item}) =>
<ListItem
title={item.title}
subTitle={item.description}
image={item.image}
onPress={() => console.log('message selected', item)}
renderRightActions={ListItemDeleteAction}/>
}
ItemSeparatorComponent={ListItemSeperator}
/>
</Screen>
Where the renderRightActions={ListItemDeleteAction} is just another component which holds a View with some style:
function ListItemDeleteAction(props) {
return (
<View style={styles.container}></View>
);
}
Any help would be highly appreciated, Thank you in advance!
The answer was that I needed to use GestureHandlerRootView to wrap everything!
import React from 'react';
import {View, StyleSheet, Image, TouchableHighlight } from 'react-native';
import Swipeable from 'react-native-gesture-handler/Swipeable';
import {GestureHandlerRootView} from 'react-native-gesture-handler';
import colors from '../config/colors';
import AppText from './AppText';
function ListItem({title, subTitle, image, onPress, renderRightActions}) {
return (
<GestureHandlerRootView>
<Swipeable renderRightActions={renderRightActions}>
<TouchableHighlight
underlayColor={colors.lightGrey}
onPress={onPress}>
<View style={styles.container}>
<Image style={styles.image} source={image} />
<View style={styles.textContainer}>
<AppText style={styles.title}>{title}</AppText>
<AppText style={styles.subTitle}>{subTitle}</AppText>
</View>
</View>
</TouchableHighlight>
</Swipeable>
</GestureHandlerRootView>
);
}
Now the component works on android.
I am new in react native, making a basic app that will find no of cases of corona in every country
so i have made 2 component both on separate file. how to switch from child to child component ?
Now i want to switch between them when i click on a button using stack navigator
App.js
import 'react-native-gesture-handler';
import React from 'react';
import { NavigationContainer } from '#react-navigation/native';
import { createStackNavigator } from '#react-navigation/stack';
import Splash from './scenes/splash';
import Corona from './scenes/corona';
const Stack = createStackNavigator();
export default function App() {
return (
<NavigationContainer>
<Stack.Navigator initialRouteName="Splash">
<Stack.Screen name="Splash" component={Splash} />
<Stack.Screen name="Corona" component={Corona} />
</Stack.Navigator>
</NavigationContainer>
);
}
splash.js
import React from 'react'
import { StyleSheet, Text, View, Image, Button} from 'react-native';
export default function splash({navigation}) {
return (
<View style={styles.container}>
<Image
source={require('../assets/corona.jpg')}
resizeMode="cover" style={styles.img} />
<Text style={styles.txt}>
Track the current status {"\n"}
of the COVID-19 and{"\n"}
stay up to date.</Text>
<Text
style={styles.btn}
onPress={() => this.props.navigation.navigate('Corona')}
>Continue</Text>
</View>
)
}
corona.js (navigate to here)
import React from 'react'
import { StyleSheet, Text, View, Image, Button} from 'react-native';
export default function corona({navigation}) {
return (
<div>
<View>
<Text>Hello next screen</Text>
</View>
</div>
)
}
In splash.js
change
<Text style={styles.btn}
onPress={() => this.props.navigation.navigate('Corona')}>Continue</Text>
to
<Text style={styles.btn}
onPress={() => navigation.navigate('Corona')}>Continue</Text>
And in corona.js
Remove <div> tags in return, react-native doesn't support div tags
Hope this helps!
I have a requirement where I want to hide the refresh indicator completely of Refresh Control for Android. I already set most of the color properties to transparent by still see gray circular indicator. Is there any way to completely hide this circular indicator. Link to gif about what is hapenning: http://imgur.com/dkAmkC6
This is my code:
import React, {Component} from 'react';
import {
StyleSheet,
Text,
TextInput,
View,
FlatList,
Dimensions,
RefreshControl,
ToastAndroid,
} from 'react-native';
import Constants from './Constants';
export default class TestList extends Component {
constructor(props) {
super(props);
this.rows =[{id: 1},{id: 2},{id: 3},{id: 4}];
this.state = {
refreshing: false,
}
}
renderItem(row) {
return (
<Text style={{fontSize: 20, borderBottomWidth: 1, borderColor: 'red', color: 'blue', height:80}}>{row.item.id}</Text>
)
}
render() {
return (
<View style={[styles.container]}>
<FlatList
data={this.rows}
renderItem={this.renderItem.bind(this)}
overScrollMode='always'
style={{flex: 1}}
keyExtractor={(item) => item.id}
removeClippedSubviews={false}
keyboardShouldPersistTaps='always'
refreshControl={
<RefreshControl
colors={['transparent']}
style={{backgroundColor: 'transparent'}}
progressBackgroundColor='transparent'
refreshing={this.state.refreshing}
onRefresh={() =>
ToastAndroid.show('Refresh completed with short duration', ToastAndroid.SHORT)}/>}
ref="FlatList"/>
</View>
)
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
},
})
[1]: http://imgur.com/dkAmkC6
You can use Platform api from react native.
import { Platform } from 'react-native'
<Flatlist
...other props
refreshControl={
Platform.select({
ios: (
<RefreshControl
colors={['transparent']}
style={{backgroundColor: 'transparent'}}
progressBackgroundColor='transparent'
refreshing={this.state.refreshing}
onRefresh={() =>
ToastAndroid.show(
'Refresh completed with short duration',
ToastAndroid.SHORT
)
}
/>
)
})
}
/>
You could conditionally render the RefreshControl component so that it only renders when you want it to.
The react docs discuss some techniques here: https://facebook.github.io/react/docs/conditional-rendering.html
But for simplicity's sake, I prefer to use the https://github.com/ajwhite/render-if npm module to conditionally render the component based on a flag in your component's state or in a redux store.
I had the same issue and wanted the same thing, but did not get it for android, so I tried the prop. progressViewOffset={number}, up-to such that the pull to refresh worked as well as the loading icon was hidden(was above the view). This is not proper solution but it worked for me.
This works for me on iOS (have not tested on Android):
refreshControl={
<RefreshControl
refreshing={false}
onRefresh={this.onRefreshHandler.bind(this)}
title='Pull to refresh'
tintColor='transparent'
/>
}
I need to use drawer from native base into react native app for both android ios et android.
Here is the link for native base http://nativebase.io/docs/v2.0.0/components#drawer and below you'll find my code :
import { Container, Header, Title, Content, Button, Icon, Left, Body, Text } from 'native-base';
import { Drawer } from 'native-base';
import SideBar from '../components/SideBar';
class App extends Component {
closeDrawer = () => {
this._drawer._root.close();
}
openDrawer = () => {
alert('open');
this._drawer._root.open();
}
render() {
return (
<Container>
<Header style={{ backgroundColor: '#C0C0C0' }}>
<Left>
<Button transparent onPress={this.openDrawer.bind(this)}>
<Icon style={style.icon} name='menu' />
</Button>
</Left>
<Body style={style.body}>
<Title style={{ color: '#FFF'}}> title </Title>
</Body>
</Header>
<Content>
<Drawer
ref={(ref) => { this._drawer = ref; }}
content={<SideBar />} >
</Drawer>
</Content>
</Container>
);
}
the alert in the method open drawer is working fine, so i know it's not a problem in the button.
I believe you want to wrap everything in the drawer, like so
render() {
return (
<Drawer
ref={(ref) => { this._drawer = ref; }}
content={<SideBar />} >
<Container>
<Header style={{ backgroundColor: '#C0C0C0' }}>
<Left>
<Button transparent onPress={this.openDrawer.bind(this)}>
<Icon style={style.icon} name='menu' />
</Button>
</Left>
<Body style={style.body}>
<Title style={{ color: '#FFF'}}> title </Title>
</Body>
</Header>
<Content>
// Your other content here
</Content>
</Container>
</Drawer>
);
}
Also, on your self-made sidebar component - make sure it has a backgroundColor. Set it to something like #F0F0F0 otherwise it ends up looking mighty strange.
I am writing answer for anyone who is new to developing apps using react native, for this answer the important thing which I will be using is react-navigation.
First is the app.js where we declare the drawer and the other screens which includes a login screen without the drawer menu. The authLoading Screen is used to navigate the users to login or home screen based on the fact whether they are authenticated or not.
App.js
const HomeScreenRouter = createDrawerNavigator(
{
Home: { screen: HomeScreen }
},
{
contentComponent: props => <SideBar {...props} />
}
);
const AuthStack = createStackNavigator({ SignIn: SignInScreen });
export default createAppContainer(createSwitchNavigator(
{
AuthLoading: AuthLoadingScreen,
App: HomeScreenRouter,
Auth: AuthStack,
},
{
initialRouteName: 'AuthLoading',
}
));
with the contentComponent we get the sliding menu in our home screen the Sidebar is a simple component which can have things as desired. Now for the homescreen we will have a button which will also allow users to open the menu from anywhere.
class HomeScreen extends React.Component {
render() {
return (
<Container>
<Header>
<Left>
<Button
transparent
onPress={() => this.props.navigation.openDrawer()}>
<Icon name="menu" />
</Button>
</Left>
<Body>
<Title>Be-in</Title>
</Body>
<Right />
</Header>
<Content>
</Content>
</Container>
);
}
}
export default HomeScreen
versions used in this example are
"react": "16.6.1",
"react-native": "0.57.7",
"react-navigation": "^3.0.8",
I hope it will be helpful to anyone who is intending to implement a drawer and also enable navigation.
Thanks for your reading,I am a beginner into React Native,I find a similar question title on this site, but my question is different from that.
I use TouchableHighlight to press to open a new screen,I have succeeded. But the button did not change color. is that normal?
There are some of my try:
I try to use TouchableOpacity:The button will change it opacity and then open new screen
I also try to use TouchableNativeFeedback:The button behaves normally once,when i tap second time it has no behavior unless i have a long press.
when i use the button to do something else, not to open a new screen, it behaves correctly.
Here is my code:
import React from 'react';
import {
StyleSheet,
Text,
View,
Image,
TouchableHighlight,
} from 'react-native';
import MyInfoOrder from './MyInfoOrder';
export default class MyInfo extends React.Component{
_onPress(){
console.log("tap");
}
_onPressMessage(){
const { navigator } = this.props;
if(navigator) {
navigator.push({
name: 'order',
component: MyInfoOrder,
})
}
}
render(){
return(
<View style={styles.btnGroup}>
<TouchableHighlight style={[styles.btnItem]} onPress={this._onPressMessage.bind(this)}>
<View style={styles.btnItemView}>
<Image source={require('../images/myinfo/message.png')} style={styles.btnItemViewImage} />
<Text style={styles.btnItemViewText}>MyTest</Text>
<Image source={require('../images/more.png')} style={styles.btnItemViewArrow} />
</View>
</TouchableHighlight>
<View style={styles.lineStyle}></View>
<TouchableHighlight style={[styles.btnItem]} onPress={this._onPress}>
<View style={styles.btnItemView}>
<Image source={require('../images/myinfo/friends.png')} style={styles.btnItemViewImage} />
<Text style={styles.btnItemViewText}>MyTest</Text>
<Image source={require('../images/more.png')} style={styles.btnItemViewArrow} />
</View>
</TouchableHighlight>
<View style={styles.lineStyle}></View>
<TouchableHighlight style={[styles.btnItem]} onPress={this._onPress}>
<View style={styles.btnItemView}>
<Image source={require('../images/myinfo/col.png')} style={styles.btnItemViewImage} />
<Text style={styles.btnItemViewText}>MyTest</Text>
<Image source={require('../images/more.png')} style={styles.btnItemViewArrow} />
</View>
</TouchableHighlight>
</View>
)
}
}
const styles = StyleSheet.create({
btnGroup:{
marginBottom:30,
borderRadius:10,
backgroundColor:'#FFFFFF',
},
btnItem:{
height:104,
borderRadius:10,
},
btnItemView:{
borderRadius:10,
backgroundColor:'#FFFFFF',
height:106,
flexDirection:'row',
alignItems:'center',
},
btnItemViewImage:{
width:48,
height:48,
marginLeft:24,
marginRight:24
},
btnItemViewText:{
flex:1,
fontSize:32,
color:'#333333',
},
btnItemViewArrow:{
width:30,
height:30,
marginRight:30
},
})
I use:
"react": "15.4.2",
"react-native": "0.41.2",
platform:android 6.0
Adjust "delayPressIn" props in TouchableHighlight to 0 and everything work as expected.
if you want change color of TouchableHighlight when pressed you need to add
underlayColor in props