updating navigation parameters in react navigation - react-native

I am trying to navigate to the same screen from two different place and passing different parameters to show additional contents.
Navigation code
// I am navigating to Worklogs screen from both places.
// In the first case only passing the current date as parameter
// and in the second case one extra parameter showPending
<View style={styles.row}>
// first touchable. don't want to show pending worklogs if navigated using this
<Touchable
style={styles.widgets}
onPress={() => this.navigateToScreen('Worklogs', {date: this.getToday()})}
>
<View style={{ flex: 1}}>
<View style={{ flex: 2, alignItems: 'center' }}>
<Image
source={require('../assets/images/todayworklog.png')}
style={{ resizeMode: 'contain', height: 50}}
/>
</View>
<View style={{ flex: 1 }}>
<Text> Today Worklog </Text>
<Text style={{ alignSelf: 'center', fontSize: 12, color: '#33b0df' }}>{worklogs.total_time} Hours</Text>
</View>
</View>
</Touchable>
// 2nd touchable. show pending worklogs if navigated from here
<Touchable
style={styles.widgets}
onPress={() => this.navigateToScreen('Worklogs', {date: this.getToday(), showPending: true})}
>
<View style={{ flex: 1}}>
<View style={{ flex: 2, alignItems: 'center' }}>
<Image
source={require('../assets/images/pendingworklog.png')}
style={{ resizeMode: 'contain', height: 50}}
/>
</View>
<View style={{ flex: 1 }}>
<Text> Pending Worklog </Text>
</View>
</View>
</Touchable>
</View>
// navigate to screen code
navigateToScreen(screenName, parameters) {
if(this.isEmpty(parameters)) {
this.props.navigation.navigate(screenName);
} else {
this.props.navigation.navigate(screenName, parameters);
}
}
In the render method of Worklogs screen I am checking for the showPending value to render an additional component.
const { params } = this.props.navigation.state;
{ (params && params.showPending)
? <PendingWorklogList pendingWorklogs={this.state.pending_worklogs} />
: <View />
}
Now if I navigate to Worklogs screen by tapping the first <Touchable />, showPending is not in the parameters and <PendingWorklogList /> component is not being rendered. Navigating from the 2nd <Touchable /> adds showPending to the parameters and <PendingWorklogList /> is rendered.
But if I go back and navigate to Worklogs again by tapping the first <Touchable /> the showPending parameter is still present so <PendingWorklogList /> is being rendered. But I would like to render <PendingWorklogList /> only if I navigate from the 2nd <Touchable />.

Related

How to switch from camera button to video record button in react native

I have camera capture button and video recording button on the same container, I want to be able to have camera button when app is launched, then when I a tap Text "Video", the it will switch to video button to record. I have a screenshot of beautyplus app as sample of what I mean
Camera button navigation
return (
<View style={styles.action}>
<View style={{ flexDirection: 'row', justifyContent: 'space-between', paddingHorizontal: 20, marginBottom: 15, alignItems: 'flex-end' }}>
<TouchableOpacity onPress={this.toggleTorch.bind(this)}>
{ this.state.flashon == RNCamera.Constants.FlashMode.off? (
<Icon
name="md-flash-off"
color="black"
size={30}
/>
) : (
<Icon
name="md-flash"
color="black"
size={30}
/>
)
}
</TouchableOpacity>
<View style={{ alignItems: 'center' }}>
<TouchableOpacity onPress={this.takePicture} style={styles.captureBtn} />
</View>
<View style={{ alignItems: 'center' }}>
<TouchableOpacity onPress={this.recordVideo} style={styles.captureVideoBtn}>
{
this.state.recording ?
(<Text>{this.secondsToMMSS(this.state.seconds)}</Text>) :
(null)
}
</TouchableOpacity>
</View>
<TouchableOpacity
onPress={this.reverseCamera}
>
<Icon
name="md-reverse-camera"
color="black"
size={30}
/>
</TouchableOpacity>
</View>
</View>
)
}
}
</RNCamera>
</View>
);
};
}
What is the problem with condition checking?
constructor() {
...
this.state = {capture:'photo'}; // default to photo
}
captureVideo=()=> {...}
capturePhoto=()=> {...}
captureAudio=()=>{...}
capture() {
swicth (this.state.capture)
case 'audio' : captureAudio()
...
}
render () {
...
<TouchableOpacity onPress={()=>this.setState({capture:'video'})}>
<Text>Video</Text></TouchableOpacity>
<TouchableOpacity onPress={()=>this.startCapture()}><Text>Start</Text>
</TouchableOpacity>
<TouchableOpacity onPress={()=>this.setState({capture:'photo'})}>
<Text>Video</Text></TouchableOpacity>
...
}

Multiple item data. Show the data as clicked in the dynamically modal with react-native

FOOD> PIZZA> clicking on any pizza opens a modal. I want to show the information of the pizza clicked in this modal. I looked at many similar examples but I could not get out of it. So I need help. I add some parts of the code below. At the same time, the code is available in the expo and the link below
snack.expo.io/#ibrahimyolbir/e48b05
accordion
<Accordion
dataArray={this.state.menus}
animation={true}
expanded={true}
renderHeader={this._renderHeader}
renderContent={this._renderContent}
/>
my open modal button in the render content
onPress={this.triggerModal(food)}
_renderContent = (item) => {
return (
<List>
{
item.food.map((food, index) => {
return (
<ListItem style={{
backgroundColor: "#f0f0f5",
padding: 10,
marginLeft: 0,
paddingRight: 10,
fontStyle: "italic",
listStyleType: "none",
flexDirection: "row",
justifyContent: "space-between"
}}>
<TouchableOpacity
onPress={this.triggerModal(food)}
style={{
flexDirection: "row",
justifyContent: "space-between"
}}
>
<Left style={{
maxWidth: 57
}}>
<Thumbnail source={require("../assets/images/left-food-icon.png")} />
</Left>
<Body>
<Text >{food.name}</Text>
<Text note >{food.description}</Text>
</Body>
<Right>
<Text >{food.price} :-</Text>
</Right>
</TouchableOpacity>
</ListItem>
)
}
)
}
</List>
);
}
MODAL
<Modal
style={{ marginTop: 122 }}
isVisible={this.state.display}
visible={this.state.display}
onSwipeComplete={() => this.setState({ isVisible: false })}
onSwipeThreshold={1}
swipeDirection="down"
animationType="slide"
onRequestClose={() => {
Alert.alert('Modal has been closed.');
}}>
<View style={{ flex: 1, backgroundColor: "#fff" }}>
<Text>Hello!</Text>
<TouchableOpacity onPress={this.closeDisplay} style={{ marginTop: 40, marginLeft: 150 }}>
<Text> CLOSE MODAL </Text>
</TouchableOpacity>
{/* <Text> {this.state.menus} </Text> */}
</View>
</Modal>
One of the way can be:
1)Create a new state
currentChildData:[],
currentParentData:[],
2)Pass parent id and child index in onPress event
<TouchableOpacity onPress={()=>this.triggerModal(item.id,index)}
3)Using that passed index and parent id,we can extract relevant information about(to be clicked item) from menus state
triggerModal = (ParentIndex,childIndex) => {
this.setState(prevState => {
let ParentData=[...prevState.menus].find(each=>each.id==ParentIndex)
return {
display: true,
currentChildData: ParentData.food[childIndex],
currentParentData: ParentData,
}
});
}
4)Now we have information of(to be clicked item) in our state. We then can use it like (name of item shown below) inside Modal
<Text>{this.state.currentChildData.name}</Text>
Working Code: https://snack.expo.io/By_QVbPMI
U missed the key from mapped array in a ListItem component. Add it as a prop key={Index} .
Also U need item from map as argument in ur onPress, cuz u need to push visited/selected elements to the state. {()=>this.openModal(itemFromMap)}
And then u can manipulate with data like u need.
As I can understood u have array of objects. Object.keys(itemFromMap).map(...
And return data to the needed part of ur modalInnerContainer.

React Native Absolute Positioned Component elements onPress events not working

I created a custom dropdown component which has a transparent Scrollview with ToucableOpacity elements. However the onPress on them are not working, even though, zIndex is making them appear on top of everything else.
In the main screen, I created two elements, 1 header containing the Dropdown and 2nd one is the body which contains the rest. Its code is given below:
<View style={styles.body, {zIndex:0}}>
<View style={[styles.header,{zIndex:1}]}>
<Text style={styles.header_text}>Search In </Text>
<Dropdown items={CATEGORIES}/>
</View>
<View style={[styles.main,{zIndex:-1}]}>
<Text style={{backgroundColor:'blue'}}>I am the body</Text>
</View>
<View>
I have included the render event markup of the Dropdown element. Its code is given below:
<View style={styles.container}>
<TouchableOpacity style={styles.main_container} onPress={this.animate}>
<Text style={styles.text}>{this.state.selectedCategoryText}</Text>
<Text>-V-</Text>
</TouchableOpacity>
<View style={{zIndex:3}}>
<Animated.View style={[styles.animated_container,{opacity: this.opacity, zIndex:4}]}>
<ScrollView style={{height:60,zIndex:4}}>
{ this.data.map( (item, i)=>
<TouchableOpacity
style={{zIndex:5}}
disabled={this.state.disabled}
key={i}
onPress={()=>this.selectItem(i)}>
<Text >{item} {i}</Text>
</TouchableOpacity>
)}
</ScrollView>
</Animated.View>
</View>
</View>
Styles for Dropdown are:
container:{
zIndex:2
},
main_container:{
flexDirection: 'row',zIndex:2
},
text:{
fontFamily: fontStyles.PoppinsRegular,
fontSize: moderateScale(14)
},
animated_container:{
backgroundColor: colors.secondaryWhiteColor,
position: 'absolute',
top: '100%',
width: '100%',
zIndex:3
}
Screenshot is given as. zIndex makes the elements appear on top but i cannot trigger onPress on Toucable opacities.

Divide the whole screen into four equal parts

I want to divide the whole screen into 4 equal parts each having a clickable action and onclick a prompt should appear with a textbox and an okay button on pressing it I need to render a webview
If you are doing this in react-native then use below code. This will divide screens in four parts and with TouchableOpacity you can use click events reflection otherwise you can use simple View.
<View style={{ flex: 1 }}>
<View style={{ flex: 1 }}>
<TouchableOpacity
style={{ flex: 1, backgroundColor: 'red' }}
onPress={() => { }} // Action
>
</TouchableOpacity>
<TouchableOpacity
style={{ flex: 1, backgroundColor: 'green' }}
onPress={() => { }} // Action
>
</TouchableOpacity>
</View>
<View style={{ flex: 1 }}>
<TouchableOpacity
style={{ flex: 1, backgroundColor: 'blue' }}
onPress={() => { }} // Action
>
</TouchableOpacity>
<TouchableOpacity
style={{ flex: 1, backgroundColor: 'yellow' }}
onPress={() => { }} // Action
>
</TouchableOpacity>
</View>
</View>
Yes, you can use common styling and components but for now I use separate So, you can easily edit and test.
You can use the vw(viewport width) and vh (viewport height), and assign to all of your items
width: "50vw",
height: "50vh"
<View style={{flex: 1}}>
<View style={{flex: 1}}> </View>
<View style={{flex: 1}}> </View>
</View>

Two buttons sharing a row in react-native

I have two buttons that look like this
This is the code
render = () => (
<Image
source={require('../../images/login.jpg')}
style={[AppStyles.containerCentered, AppStyles.container, styles.background]}
>
<Image
source={require('../../images/logo.png')}
style={[styles.logo]}
/>
<Spacer size={200} />
<View style={[AppStyles.row, AppStyles.paddingHorizontal]}>
<View style={[AppStyles.flex1]}>
<Button
title={'Login'}
icon={{ name: 'lock' }}
onPress={Actions.login}
/>
</View>
</View>
<Spacer size={10} />
<View style={[AppStyles.row, AppStyles.paddingHorizontal]}>
<View style={[AppStyles.flex1]}>
<Button
title={'Sign up'}
backgroundColor={'#FB6567'}
icon={{ name: 'face' }}
onPress={Actions.signUp}
/>
</View>
</View>
</Image>
)
I want the buttons to occupy one row and possibly share 40% - 40% of the space with the rest of the 20% going to the padding. How can i have them occupy one row?.
You'd need to define a container with flexDirection set to row and use justifyContent depending on where you want your padding:
render() {
return (
<View style={styles.container}>
<View style={styles.button} />
<View style={styles.button} />
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
flexDirection: 'row',
justifyContent: 'space-between'
},
button: {
backgroundColor: 'green',
width: '40%',
height: 40
}
});
Change space-between to space-around if you want the padding to be distributed to the sides too. (Demo)