I created a form in which I have a field called address. Where I implemented 'react-native-google-places-autocomplete' plugin. It's working fine if I don't add scrollView. But I need to add scrollView just because I have so many input fields inside that form. but then I got a warning "VirtualizedLists should never be nested inside plain ScrollViews with the same orientation".
Here is my code:
Add.js
<SafeAreaView style={{ flex: 1, paddingTop: Platform.OS === "android" ? StatusBar.currentHeight : 0, backgroundColor: 'white' }}>
<View style={{ flex: 1 }}>
<ScrollView scrollEventThrottle={16}>
<View style={{ flex: 1 }}>
<Text style={{ fontSize: 20, marginTop: 5, marginBottom: 10, paddingHorizontal: 15, fontFamily: 'Mulish-SemiBold' }}>Add Ground</Text>
<TouchableWithoutFeedback style={styles.button} onPress={(e) => this.chooseFile()}>
<Image source={this.state.avatarSource ? this.state.avatarSource : require('./../../assets/images/default-cover.jpg')} style={{ width: '100%', height: 150 }} />
</TouchableWithoutFeedback>
<View style={styles.inputWrapper}>
<Text style={styles.inputLabel}>Name</Text>
<TextInput
style={styles.input}
placeholder="e.g Drealit Stadium"
onChangeText={name => this.setState({ name })}
value={this.state.name}
autoCorrect={false}
/>
</View>
<View style={styles.inputWrapper}>
<Text style={styles.inputLabel}>Address</Text>
{/*
onChangeText={address => this.setState({ address })}
value={this.state.address}
*/}
<ScrollView>
<GooglePlacesInput />
</ScrollView>
</View>
<View style={styles.inputWrapper}>
<Text style={styles.inputLabel}>Contact Person Name</Text>
<TextInput
style={styles.input}
placeholder="e.g David Johnson"
onChangeText={organizer_name => this.setState({ organizer_name })}
value={this.state.organizer_name}
autoCorrect={false}
/>
</View>
<View style={styles.inputWrapper}>
<Text style={styles.inputLabel}>Contact Person Number</Text>
<TextInputMask
type={'cel-phone'}
options={{
maskType: 'INTERNATIONAL',
}}
placeholder="e.g 509-962-9014"
style={styles.input}
value={this.state.organizer_number}
onChangeText={organizer_number => this.setState({ organizer_number })}
/>
</View>
<View style={styles.inputWrapper}>
<Text style={styles.inputLabel}>Description</Text>
<TextInput
placeholder="e.g A Ground suitable for small side cricket tournament. Ideal for some fast paced cricket and lot of fun."
onChangeText={description => this.setState({ description })}
value={this.state.description}
autoCorrect={false}
multiline={true}
numberOfLines={4}
style={[styles.input, { height: 'auto', textAlignVertical: 'top' }]}
/>
</View>
<View style={styles.inputWrapper}>
<Text style={styles.inputLabel}>Rate per hour / day</Text>
<TextInput
style={styles.input}
placeholder="e.g 3500"
keyboardType="numeric"
onChangeText={ratePerHourDay => this.setState({ ratePerHourDay })}
value={this.state.ratePerHourDay}
autoCorrect={false}
/>
</View>
<View style={styles.inputWrapper}>
<Text style={styles.inputLabel}>Rate per hour / night</Text>
<TextInput
style={styles.input}
placeholder="e.g 4500"
keyboardType="numeric"
onChangeText={ratePerHourNight => this.setState({ ratePerHourNight })}
value={this.state.ratePerHourNight}
autoCorrect={false}
/>
</View>
<View style={{ marginHorizontal: 15, marginVertical: 10 }}>
<TouchableWithoutFeedback style={styles.button} onPress={(e) => this.manageAddGround(e)}>
<LinearGradient
colors={["#4678f6", "#4475ee", "#5053eb"]}
start={{ x: 0, y: 0 }}
end={{ x: 0, y: 0 }}
locations={[0, 0.5, 0.6]}
style={styles.appButtonContainer}
>
<Text style={styles.buttonText}>Save</Text>
</LinearGradient>
</TouchableWithoutFeedback>
</View>
</View>
</ScrollView>
</View>
</SafeAreaView>
GooglePlacesInput.js
<View style={{ flex: 1 }}>
<GooglePlacesAutocomplete
placeholder='e.g 640 Cross Creek Dr, Ellensburg, WA, 98926'
query={{
key: GOOGLE_PLACES_API_KEY,
language: 'en',
}}
enablePoweredByContainer={false}
onPress={(data, details = null) => {
console.log("GooglePlacesInput -> data", data)
}}
debounce={200}
styles={{
textInputContainer: {
backgroundColor: '#fff',
borderTopWidth: 0,
borderBottomWidth: 0,
},
textInput: {
marginLeft: 0,
marginRight: 0,
height: 40,
borderBottomWidth: 1,
color: '#000',
borderBottomColor: '#dedede'
},
predefinedPlacesDescription: {
color: '#1faadb',
},
listView: {
backgroundColor: '#fff',
borderWidth: 0.5,
borderColor: '#dedede',
shadowColor: '#000',
shadowOffset: {
width: 0,
height: 6,
},
shadowOpacity: 0.05,
shadowRadius: 10,
elevation: 4
}
}}
/>
</View>
You are receiving this warning because react-native-google-places-autocomplete renders a component to show results, and you have wrapped in a .
It's a warning, not an error. If it works for you can leave it as is.
Related
My app have structure like this,
MapPage.js that contain expo-barcode-scanner wrapped with Modal and MapView.
DetailsPage.js that contain search result/products' details.
User can use the barcode scanner or TextInput(also in MapPage, not wrapped in Modal) to search product ID and the app will navigate to DetailsPage for result. If result is not found, app will automatically navigate.goBack() to MapPage. If result existed, will goto the result and stay in DetailsPage.
User can also navigate to DetailsPage by pressing marker callout on MapView.
Here is situation:
user press on marker callout(navigate to DetailsPage), then press back(navigate.goBack()) to MapPage : No lagging
user search by TextInput, then back to MapPage: No lagging whether search result exist or not
user search by Barcode, result not exist, automatically back to MapPage: not lagging
user search by Barcode, result existed, stay in DetailsPage, user manually press back: LAGGING
Below codes for your references
//MapPage
<MapView
style={{ width: '100%', height: '100%' }}
provider={PROVIDER_GOOGLE}
showsMyLocationButton={true}
showsUserLocation={true}
region={{
latitude: region.latitude,
longitude: region.longitude,
latitudeDelta: region.latitudeDelta,
longitudeDelta: region.longitudeDelta,
}}>
<MapMarker
markerLocation={markers}
countryCode={country.countryCode}
/>
</MapView>
...
<TextInput
placeholder={
i18n.t('SearchId')
}
placeholderTextColor="white"
onSubmitEditing={() =>
handleBarCodeScanned({ data: textSearchData })
}
onChangeText={(text) => {
settextSearchData(text.toUpperCase());
}}
/>
<Pressable onPress={() => setqrcodeModalVisi(true)}>
<Ionicons
name="qr-code-outline"
size={33}
color="white"
/>
</Pressable>
...
<Modal
visible={qrcodeModalVisi}
animationType="slide"
onRequestClose={() => setqrcodeModalVisi(false)}
transparent={true}>
<View>
<Pressable onPress={() => setqrcodeModalVisi(false)}>
<Feather
name="x"
size={24}
color="white"
/>
</Pressable>
{!hasPermission && (
<View>
<Text
style={{
color: colors.text,
}}>
Camera access denied.
</Text>
<Pressable onPress={() => getBarCodeScannerPermissions()}>
<Text style={{ color: colors.secondary }}>
Goto setting page
</Text>
</Pressable>
</View>
)}
{hasPermission && (
<View
style={{
flex: 1,
justifyContent: 'center',
alignItems: 'center',
}}>
<BarCodeScanner
onBarCodeScanned={
scanned ? undefined : handleBarCodeScanned
}
style={{
width: '100%',
height: '80%',
}}
/>
</View>
)}
</View>
</Modal>
//MapMarker
<View>
{markerLocation.map((array) => (
<Marker
key={array.title}
coordinate={{
latitude: array.latitude,
longitude: array.longitude,
}}
image={require('../../../assets/icons/map_marker.png')}
title={''}
description={''}
onCalloutPress={() => handleMapMarkerPress(array.regionCode)}>
<Callout>
<View
style={{
backgroundColor: 'white',
width: 180,
paddingVertical: 5,
alignItems: 'center',
justifyContent: 'center',
}}>
<Text
style={{
width: '80%',
textAlign: 'center',
color: colors.secondary,
fontWeight: 'bold',
}}>
{array.title}
</Text>
<View
style={{
backgroundColor: colors.secondary,
width: '80%',
height: 25,
alignItems: 'center',
justifyContent: 'center',
marginTop: 2,
flexDirection: 'row',
marginVertical: 5,
}}>
<Text style={{ color: 'white', fontWeight: 'bold' }}>
{i18n.t('MapMarkerBtn')}
</Text>
</View>
</View>
</Callout>
</Marker>
))}
</View>
Thanks!
ListHeaderComponent inside flatlist doesn't work. It won't render nothing in header (above flatlist). If I however put some custom component it does work but it doesn't with my renderHeader function. I tried making a custom component with the same view as in renderHeader but when I used that nothing rendered so I don't know
My flatlist along with whole render:
render() {
const { height } = Dimensions.get("window");
return (
<View style={{flex: 1,
backgroundColor: "#EBECF4"}}>
{/* <Text>
Connection Status :{" "}
{this.state.connection_status ? "Connected" : "Disconnected"}
</Text> */}
{/* <Loader loading={this.state.loading} /> */}
<StatusBar backgroundColor="#63003d" barStyle="light-content" />
<SafeAreaView>
<ModernHeader
backgroundColor="#63003d"
height={50}
text="Eleph"
textStyle={{
color: "white",
fontFamily: "Lobster-Regular",
//fontWeight: "bold",
fontSize: 25,
}}
leftIconComponent={
<TouchableOpacity
style={{ marginRight: 0, margin: 0 }}
onPress={() =>
this.props.navigation.dispatch(DrawerActions.openDrawer())
}
>
<FontAwesome5 name="bars" size={22} color="white" />
</TouchableOpacity>
}
rightIconComponent={
<TouchableOpacity
style={{ marginLeft: 0, margin: 0 }}
onPress={() => this.props.navigation.navigate("Profile")}
>
{/* <MaterialCommunityIcons
name="chart-areaspline"
size={24}
color="#639dff"
/> */}
<Foundation name="graph-bar" size={24} color="white" />
{/* <FontAwesome name="bar-chart" size={24} color="white" /> */}
</TouchableOpacity>
}
/>
</SafeAreaView>
<FlatList
//contentInset={{ top: HEADER_HEIGHT }}
//contentOffset={{ y: -HEADER_HEIGHT }}
data={this.state.post}
extraData={this.state.post}
keyExtractor={(item) => item.id.toString()}
style={{
marginHorizontal: 0,
marginVertical: 6,
}}
renderItem={({ item }) => this.renderPost(item)}
ListFooterComponent={this.renderFooter}
ListHeaderComponent={this.renderHeader}
refreshControl={
<RefreshControl
style={{ color: "#639dff" }}
tintColor="#639dff"
titleColor="#fff"
refreshing={this.state.isLoading}
onRefresh={this.onRefresh}
/>
}
initialNumToRender={7}
onEndReachedThreshold={0.1}
showsVerticalScrollIndicator={false}
onEndReached={() => {
if (
!this.onEndReachedCalledDuringMomentum &&
!this.state.isMoreLoading
) {
this.getMore();
}
}}
onMomentumScrollBegin={() => {
this.onEndReachedCalledDuringMomentum = false;
}}
onScroll={(e) => {
scrollY.setValue(e.nativeEvent.contentOffset.y);
}}
></FlatList>
{/* <View style={styles.footer}>
<TouchableOpacity
activeOpacity={0.9}
onPress={this.getMore}
style={styles.loadMoreBtn}
>
<Text style={styles.btnText}>See more moods</Text>
{this.state.loading ? (
<ActivityIndicator color="white" style={{ marginLeft:8 }} />
) : null}
</TouchableOpacity>
</View> */}
</SafeAreaView>
</View>
My renderHeader function:
renderHeader = () => {
return (
<View
style={{
flex: 1,
flexDirection: "row",
backgroundColor: "#ffffff",
//width: "100%",
padding: 11,
alignItems: "center",
position: "absolute",
justifyContent: "center",
//top: 50,
//bottom: 0,
//left: 0,
//elevation: 4,
//right: 0,
//height: 50,
}}
//flexDirection: "row",
//backgroundColor: "#ffffff",
//width: "100%",
//padding: 11,
//alignItems: "center",
>
<TouchableOpacity
onPress={() => this.props.navigation.navigate("Post")}
>
<Text
style={{ alignItems: "center", color: "#C4C6CE" }}
//placeholder={How are you feeling right now ${this.state.user.name}?}
multiline
>{Tell us how are you feeling right now ${this.state.user.name}?}</Text>
</TouchableOpacity>
{/* <View style={styles.divider}></View> */}
</View>
);
}
Why for example renderFooter works??
renderFooter = () => {
if (!this.state.isMoreLoading) return true;
return (
<ActivityIndicator
size="large"
color={"#D83E64"}
style={{ marginBottom: 10 }}
/>
);
};
Use ListHeaderComponentStyle to style the ListHeaderComponent.
I created a simple snack for you, check if this helps. Your code looks okay but not sure about the whole screen design. Here is my snack link.
https://snack.expo.io/#saad-bashar/excited-fudge
It might be related to the other components inside your screen. So first check only with flatlist, remove all other components. Hope you can sort it out :)
The solution is to remove the "absolute" style in the header for flatlist. The question is mine im just answering with different account but this is the solution that worked.
I am trying to use a CustomCallout with a ImageBackground in it. I notice a really strange behavior when testing the application on two different devices (both Android). The image is showed correctly on the older device with lower display, but on the new device (p30 lite) the image is not appearing.. any ideas? here is my code:
class CustomCallout extends React.Component {
constructor(props) {
super(props);
}
render() {
return (
<View style={styles.calloutStyle}>
<View>
<View style={{ ...styles.placeRow, ...styles.placeHeader }}>
<ImageBackground
source={{ uri: this.props.image }}
style={styles.bgImage}
>
<View style={styles.titleContainer}>
<Text style={styles.title} numberOfLines={1}>
{this.props.placeName}
</Text>
</View>
</ImageBackground>
</View>
<View style={{ ...styles.placeRow, ...styles.placeDetail }}>
<Text>{this.props.distance}m</Text>
<Text>{this.getPlaceType(this.props.placeType)}</Text>
</View>
<View style={{ ...styles.placeRow, ...styles.placeRating }}>
<StarRating
disabled={false}
emptyStar={'ios-star-outline'}
fullStar={'ios-star'}
halfStar={'ios-star-half'}
iconSet={'Ionicons'}
maxStars={7}
rating={4}
fullStarColor={'#FDCC0D'}
starSize={20}
/>
</View>
</View>
</View>
);
}
}
CustomCallout.propTypes = propTypes;
const styles = StyleSheet.create({
calloutStyle: {
height: 200,
width: 280,
backgroundColor: '#61adc8',
shadowOffset: { width: 0, height: 2},
shadowRadius: 6,
shadowOpacity: 0.26,
elevation: 55,
padding: 12,
borderRadius: 20,
shadowColor: 'black',
overflow: 'hidden'
},
bgImage: {
width: '100%',
height: '100%',
justifyContent: 'flex-end',
},
placeRow: {
flexDirection: 'row'
},
placeHeader: {
height: '80%'
},
placeDetail: {
justifyContent: 'space-between',
height: '10%'
},
placeRating: {
height: '10%',
justifyContent:'flex-start',
},
titleContainer: {
backgroundColor: 'rgba(0,0,0,0.5)',
shadowOffset: { width: 0, height: 2},
shadowRadius: 6,
shadowOpacity: 0.26,
elevation: 55,
borderRadius: 10,
alignItems: 'center'
},
title: {
color: 'white',
fontSize: 20
}
});
export default CustomCallout;
We cant put ImageBackground wherever we want.. I don't know the exact theory. But Just put the ImageBackgroung tag outside the view and try to even put on different views too.. If anyone know plz correct me. Here is a working example.
Put ImageBackground to entire component
render() {
return (
<View style={styles.calloutStyle}>
<View>
<ImageBackground
source={{ uri: 'https://miro.medium.com/max/1200/1*mk1-6aYaf_Bes1E3Imhc0A.jpeg' }}
style={styles.bgImage}
>
<View style={{ ...styles.placeRow, ...styles.placeHeader }}>
<View style={styles.titleContainer}>
<Text style={styles.title} numberOfLines={1}>
{this.props.placeName}
</Text>
</View>
</View>
</ImageBackground>
<View style={{ ...styles.placeRow, ...styles.placeDetail }}>
<Text>{this.props.distance}m</Text>
<Text>{this.getPlaceType(this.props.placeType)}</Text>
</View>
<View style={{ ...styles.placeRow, ...styles.placeRating }}>
<StarRating
disabled={false}
emptyStar={'ios-star-outline'}
fullStar={'ios-star'}
halfStar={'ios-star-half'}
iconSet={'Ionicons'}
maxStars={7}
rating={4}
fullStarColor={'#FDCC0D'}
starSize={20}
/>
</View>
</View>
</View>
);
}
}
Or you can put to only both components
render() {
return (
<View style={styles.calloutStyle}>
<View>
<ImageBackground
source={{ uri: 'https://miro.medium.com/max/1200/1*mk1-6aYaf_Bes1E3Imhc0A.jpeg' }}
style={styles.bgImage}
>
<View style={{ ...styles.placeRow, ...styles.placeHeader }}>
<View style={styles.titleContainer}>
<Text style={styles.title} numberOfLines={1}>
{this.props.placeName}
</Text>
</View>
</View>
<View style={{ ...styles.placeRow, ...styles.placeDetail }}>
<Text>{this.props.distance}m</Text>
<Text>{this.getPlaceType(this.props.placeType)}</Text>
</View>
<View style={{ ...styles.placeRow, ...styles.placeRating }}>
<StarRating
disabled={false}
emptyStar={'ios-star-outline'}
fullStar={'ios-star'}
halfStar={'ios-star-half'}
iconSet={'Ionicons'}
maxStars={7}
rating={4}
fullStarColor={'#FDCC0D'}
starSize={20}
/>
</View>
</ImageBackground>
</View>
</View>
);
}
}
or put ImageBackground to inside view only
render() {
return (
<View style={styles.calloutStyle}>
<View>
<ImageBackground
source={{ uri: 'https://miro.medium.com/max/1200/1*mk1-6aYaf_Bes1E3Imhc0A.jpeg' }}
style={styles.bgImage}
>
<View style={{ ...styles.placeRow, ...styles.placeHeader }}>
<View style={styles.titleContainer}>
<Text style={styles.title} numberOfLines={1}>
{this.props.placeName}
</Text>
</View>
</View>
</ImageBackground>
<View style={{ ...styles.placeRow, ...styles.placeDetail }}>
<Text>{this.props.distance}m</Text>
<Text>{this.getPlaceType(this.props.placeType)}</Text>
</View>
<View style={{ ...styles.placeRow, ...styles.placeRating }}>
<StarRating
disabled={false}
emptyStar={'ios-star-outline'}
fullStar={'ios-star'}
halfStar={'ios-star-half'}
iconSet={'Ionicons'}
maxStars={7}
rating={4}
fullStarColor={'#FDCC0D'}
starSize={20}
/>
</View>
</View>
</View>
);
}
}
Try this out and let me know the result.. :)
I am creating a render method where it displays information from a state array, and I want it so that when a user touches a Card a Modal will open presenting the same information.
My code is as follows:
this.state = {
fontLoaded: false,
feed: [{
username: ["Jeff", "Kyle", "David"],
caption: ["Great", "Amazing", "Not so Good"],
comments: ["Comment 1", "Comment 2", "No Comment"],
photo:[Pic1,Pic2,Pic3],
}]
}
state = {
isModalVisible: false,
};
toggleModal = () => {
this.setState({ isModalVisible: !this.state.isModalVisible });
};
renderFeed = () => {
return this.state.feed.map((card, index) => {
return card.username.map((username, i) => {
if(card.caption[i])
return (
<View>
<TouchableHighlight onPress={this.toggleModal} underlayColor="white">
<Card
key={`${i}_${index}`}
image={card.photo[i]}
containerStyle={{borderRadius:10, marginRight:1, marginLeft:1,}}>
<View
style={{ flex: 1, flexDirection: 'row', justifyContent: 'space-between' }}
>
<View style={{ flexDirection: 'row'}}>
<Avatar
size="small"
rounded
source={card.photo[i]}
/>
</View>
<View style={{flexDirection:'row'}}>
<Avatar
rounded
icon={{ name:'heart-multiple-outline', type:'material-community', color: '#ff4284'}}
overlayContainerStyle={{marginLeft:5}}
reverse
size='small'/>
<Avatar
reverse
rounded
icon={{ name:'comment-processing-outline', type:'material-community' }}
overlayContainerStyle={{backgroundColor: '#dbdbdb',marginLeft:5}}
size='small'/>
</View>
</View>
{ this.state.fontLoaded == true ? (
<View style={{flexDirection:'row'}}>
<Text style={{fontFamily: 'MontserratB', color:'#bf00b9', marginTop:10}}>{username}</Text>
<Text style={{fontFamily:'Montserrat', marginTop:10}}>{card.caption[i]}</Text>
</View>
) : (<Text> Loading...</Text>)
}
<Text style={{marginTop:4, color:'#878787'}}>{card.comments[i]}</Text>
</Card>
</TouchableHighlight>
<Modal
animationIn="zoomInDown"
animationOut="zoomOutDown"
animationInTiming={700}
animationOutTiming={600}
backdropTransitionInTiming={600}
backdropTransitionOutTiming={600}
isVisible={this.state.isModalVisible}>
<Image source={card.photo[i]}
style={{width: SCREEN_WIDTH - 20,
height: 300, justifyContent: 'center', alignSelf:
'center' }}/>
<Card
containerStyle={{ width: SCREEN_WIDTH - 20, marginTop: 0, justifyContent: 'center', alignSelf:
'center' }}>
<View style={{ flexDirection:'row' }}>
<Avatar
size="small"
rounded
source={card.photo[i]}
/>
<View style={{ flex:2, flexDirection:'row', justifyContent:'flex-end' }}>
<Avatar
rounded
icon={{ name:'heart-multiple-outline', type:'material-community'}}
overlayContainerStyle={{backgroundColor: '#ff4284',marginLeft:5}}
reverse
size='small'/>
<Avatar
reverse
rounded
icon={{ name:'comment-processing-outline', type:'material-community' }}
overlayContainerStyle={{backgroundColor: '#dbdbdb',marginLeft:5}}
size='small'/>
</View>
</View>
<View style={{ flexDirection:'row' }}>
<Text style={{fontFamily: 'MontserratB', color:'#bf00b9', marginTop:10}}>{username}</Text>
<Text style={{fontFamily:'Montserrat', marginTop:10}}>{card.caption[i]}</Text>
</View>
<Text style={{marginTop:4, color:'#878787'}}>{card.comments[i]}</Text>
</Card>
<Button style={{marginTop:0, borderBottomRightRadius: 20, borderBottomLeftRadius: 20, borderTopLeftRadius: 0, borderTopRightRadius: 0, width: SCREEN_WIDTH - 20, alignSelf: 'center', justifyContent: 'center'}} title="Close" onPress={this.toggleModal} />
</Modal>
</View>
);
return <React.Fragment />;
});
})
}
everything works perfectly except that no matter which Card is touched a Modal is opened presenting the last objects in the array. So no matter which of the three cards are pressed, a Modal will always open with the information regarding David
Modified snack version of your sample:
https://snack.expo.io/H1yHPQQdr
I have the following return() and am unable to move the last VIEW which contains the button title = 'done' to the right side
return (
<View style={styles.container}>
<Text style={styles.bigFont}>{`${this.state.timer + 'TIMER'}`}</Text>
<Text style={styles.bigFont}>{`${this.state.min + ':' + this.state.sec}`}</Text>
<View style={styles.button}>
<Button title= {this.state.startFlag ? 'PAUSE' : 'START'} onPress={()=>this.startToggle()} />
<Button title='RESET' onPress={()=>this.resetToggle()} />
</View>
<View style={styles.row}>
<Text style={[styles.bold,{marginRight:10},{width:112},
{textAlign:'right'}]}>
Work Timer:</Text>
<Text style={styles.bold}> min:</Text>
<TextInput
value={Math.floor(this.state.workTime / 60).toString()}
style={styles.input}
onChangeText={(text)=>{this.captureInput(text)}}
onSubmitEditing={()=>{(this.update('work-min'))}}
/>
<Text style={styles.bold}> sec:</Text>
<TextInput
value={Math.floor(this.state.workTime % 60).toString()}
style={styles.input}
keyboardType='numeric'
onChangeText={(text) => {this.captureInput(text)}}
onSubmitEditing={()=>{(this.update('work-sec'))}}
/>
</View>
<View style={styles.row}>
<Text style={[styles.bold,{marginRight:10},{width:112},
{textAlign:'right'}]}>
Break Timer:</Text>
<Text style={styles.bold}> min:</Text>
<TextInput
value={Math.floor(this.state.breakTime / 60).toString()}
style={styles.input}
keyboardType='numeric'
onChangeText={(text) => {this.captureInput(text)}}
onSubmitEditing={()=>{(this.update('break-min'))}}
/>
<Text style={styles.bold}> sec:</Text>
<TextInput
value={Math.floor(this.state.breakTime % 60).toString()}
style={styles.input}
keyboardType='numeric'
onChangeText={(text) => {this.captureInput(text)}}
onSubmitEditing={()=>{(this.update('break-sec'))}}
/>
</View>
<View style={{flexDirection:'row',justifyContent:'flex-end',alignItems:'flex-end'}} >
<Text ><Button title='done' onPress={()=>this.resetToggle()} /></Text>
</View>
</View>
)
export default StyleSheet.create({
container: {
flex:1,
flexDirection:'column',
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
marginBottom:150,
},
bigFont:{
fontSize:40,
color:'darkblue'
},
row:{
flexDirection:'row',
marginBottom:15,
},
button:{
flexDirection:'row',
marginTop:30,
marginBottom:30,
},
bold: {
fontWeight: 'bold',
color:'green',
},
input: {
borderWidth: 1,
borderColor: 'black',
marginRight: 10,
paddingHorizontal:15,
minWidth: 50,
},
})
so, interestingly, we need to use alignSelf:'flex-end' or use width:'100%'. flex:1 is definitely wrong as that uses all the available space and shifts everything up.
Below code should work. Last section of return statement.
<View style={{flex: 1, flexDirection: 'row', justifyContent: 'flex-end', alignItems: 'flex-end'}} >
<Text ><Button title='done' onPress={() => this.resetToggle()} /></Text>