How to model a button with icons in react-native - reactjs

I'm using react-native-icons package to include icons with buttons. They have a sample code listed in example folder. I'm trying to achieve onPress on View but turns out react-native doesn't have onPress function for <View> component.
I tried using <TouchableHighlight> but it can only have single child element in it not two like <Icon> and <Text> inside.
I also tried using <Text> with <Icon> and <Text> inside but <Text> can only have <Text> elements inside.
Has anyone have any luck achieving similar functionality ?
<View onPress={this.onBooking}
style={styles.button}>
<Icon
name='fontawesome|facebook-square'
size={25}
color='#3b5998'
style={{height:25,width:25}}/>
<Text style={styles.buttonText}>Sign In with Facebook</Text>
</View>

If you are using react-native-icons module, you can try wrap both your icon and text in a view, then use TouchableHighlight on top of it. Something like:
<TouchableHighlight onPress={()=>{}}>
<View>
<Icon ... />
<Text ... />
</View>
</TouchableHighlight>
But it will be very easy if you use a relative new module react-native-vector-icons. You can do like:
<Icon name="facebook" style={styles.icon}>
<Text style={styles.text}>Login with Facebook</Text>
</Icon>

I managed to do it like this. I wonder if there is a better way.
var styles = StyleSheet.create({
btnClickContain: {
flex: 1,
flexDirection: 'row',
justifyContent: 'center',
alignItems: 'stretch',
alignSelf: 'stretch',
backgroundColor: '#009D6E',
borderRadius: 5,
padding: 5,
marginTop: 5,
marginBottom: 5,
},
btnContainer: {
flex: 1,
flexDirection: 'row',
justifyContent: 'center',
alignItems: 'stretch',
alignSelf: 'stretch',
borderRadius: 10,
},
btnIcon: {
height: 25,
width: 25,
},
btnText: {
fontSize: 18,
color: '#FAFAFA',
marginLeft: 10,
marginTop: 2,
}
});
<TouchableHighlight
onPress={this.onBooking} style={styles.btnClickContain}
underlayColor='#042417'>
<View
style={styles.btnContainer}>
<Icon
name='fontawesome|facebook-square'
size={25}
color='#042'
style={styles.btnIcon}/>
<Text style={styles.btnText}>Sign In with Facebook</Text>
</View>
</TouchableHighlight>

Expo has a a Button component that does what you want, styling and all:
<FontAwesome.Button name="facebook" backgroundColor="#3b5998" onPress={...}>
Sign in with Facebook
</FontAwesome.Button>
<FontAwesome.Button name="twitter" backgroundColor="#1da1f2" onPress={...}>
Sign in with Twitter
</FontAwesome.Button>
What it looks like running in the iOS simulator:
If you're not using Expo, study the source and create a similar component.

Related

Text out of view in Touchable opacity React native

I'm new to react native and i'm trying to display some text in a custom touchable opacity. but the text keep exceeding the border even when i'm using flex wrap. my code is the following:
<View style={styles.main_container} >
<View style={styles.ctr1}>
<TouchableOpacity style={{ flexDirection: 'row' }} >
<Image style={styles.img} source={{ uri:`data:image/gif;base64,${encodedData}`}}/>
<View>
<Text style={styles.txt}> k </Text>
<Text style={{ flexWrap:1 }} > ddddddddddddddddddddddddddddddddddddddddd </Text>
<Text> kk </Text>
</View>
</TouchableOpacity>
</View>
</View>
and here is look of the styles i used:
main_container: {
flex: 1,
height: 300,
flexDirection: 'column',
backgroundColor: "grey",
width: '95%',
margin: 10,
},
ctr1: {
flex: 1,
flexDirection: 'row',
backgroundColor: 'white',
//margin: 2,
},
How can i wrap it
Issue was not in the <Text> element that you have given the style flexWrap:1. Problem was in the parent elements.
Adding flex: 1 to <TouchableOpacity> and <View> which contains your <text> will solve the problem.
This will do the calculation for width depends on the device width.
<View style={styEdit.main_container}>
<View style={styEdit.ctr1}>
<TouchableOpacity style={{ flexDirection: 'row', flex: 1 }} >
<Image style={styles.img} source={{ uri:`data:image/gif;base64,${encodedData}`}}/>
<View style={{ flexDirection: 'column', flex: 1 }}>
<Text style={styEdit.txt}>k</Text>
<Text>ddddddddddddddddddddddddddddddddddddddddd---</Text>
<Text>kk</Text>
</View>
</TouchableOpacity>
</View>
</View>
Tested the code in my machine.
Cheers!

ReactNative Text Style Next Line

Simply I am trying to make 3 Texts with icons align in a column
I want to give the expo icons a little margin-top so they are next to each text element
Then how can I make the next line in text aligned with the text itself
For Example The (S) in School to be vertically aligned with the (5) in 5th
I searched a lot on how to do that in react-native but with no luck
and I tried some normal CSS stuff but didn't work is it achievable?
Code :
<View style={styles.cardView}>
<Text style={styles.CardTextLayout} > <MaterialIcons name="store" size={21} color="lightgrey" /> {item.key} </Text>
<Text style={styles.locationText} > <Entypo name="location-pin" size={21} color="lightgrey" />5th Settelment, Near Akhnaton School, Cairo</Text>
<Text style={styles.locationText} > <MaterialIcons name="description" size={21} color="lightgrey" />Breif Description about the place and what is offers</Text>
</View>
Styles
CardTextLayout: {
// marginLeft: 8,
fontSize: cardResponsiveFontSize,
fontWeight: 'bold',
textAlign: 'left',
color: '#231F20',
elevation: 8,
},
locationText: {
fontSize: cardResponsiveFontSize,
textAlign: 'left',
color: '#231F20',
elevation: 8,
},
I don't know how you would do that with your current code, but you can try to set it up like this.
<View style={styles.cardView}>
<View style={styles.cardRow}>
<View style={styles.cardIcon}>{put your icon here}</View>
<View style={styles.cardText}>{put your text here}</View>
</View>
...add the other 2 rows here
</View>
And styles
cardRow: {
flexDirection: "row",
flex: 1
},
cardIcon: {
flex: 1
},
cardText: {
flex: 9
}
And add your styles for icons and text.
You can change up the cardIcon and cardText flex ratio so that you get different width for your icon.
You can make a wrapper view with alignItems: 'center' to make both text and icon vertical center
<View style={styles.cardView}>
<View style={{ flexDirection: 'row', alignItems: 'center' }}>
<MaterialIcons name="store" size={21} color="lightgrey" />
<Text style={styles.CardTextLayout}>{item.key}</Text>
</View>
.....
</View>

How to get 2 react native <view> in the same line?

I am trying to get an image viewer to work with my gallery, The library I use https://github.com/ascoders/react-native-image-viewer gives option to render a react element in the header. I am using this following element in the place of header
<View styles={modalStyles.header}>
<View onPress={props.closeModal} style={modalStyles.leftHeader}>
<Icon name="close" size={20} color="#fff"></Icon>
</View>
<View onPress={() => props.startDownload(props.getShowingImage())} style={modalStyles.rightHeader}>
<Icon name="download" size={30} color="#fff"></Icon>
</View>
</View>
and here is my styles
const modalStyles = StyleSheet.create({
header: {
flex: 1,
flexDirection: 'row',
flexWrap: 'wrap',
justifyContent: 'space-between',
backgroundColor: "red",
},
leftHeader: {
marginLeft: 20,
padding: 10,
alignSelf: 'flex-start',
backgroundColor: "red",
},
rightHeader: {
marginRight: 20,
padding: 10,
alignSelf: 'flex-end',
backgroundColor: "red",
},
})
and here is how the modal looks like
This is how i get content inline one at left and one at right. Also you have typo in your code .. rename style with styles
<View style={[{flexDirection:'row', alignItems:'center'}]}>
<View style={[{flex:1,flexDirection:'row'}]}>
//... left content
</View>
<View style={[{justifyContent:'space-evenly', marginVertical:10}]}>
// .... right content
</View>
</View>

How to horizontally center a component while there are other components in the same row?

I'm trying to mimic a stack navigation header like below:
where the title is perfectly centered while there's a return button in the same row on the left.
I have tried to use justifyContent: 'space-between' with an empty View on the right side but the title will be off center to the right a bit. How should I approach this?
my renderHeader function:
_renderHeader = () => {
return (
<View style={styles.headerAbsolute}>
<View style={styles.bar}>
<ButtonBack
text={"Resumes"}
onPress={() => this._onNavBackHandler()}
/>
{true ? (
<Text style={styles.headingFixed}>{this.state.title}</Text>
) : ( null )}
<View/>
</View>
</View>
)
}
These are the styles:
bar: {
height: 55,
flexDirection: "row",
alignItems: 'flex-end',
justifyContent: 'space-between',
paddingHorizontal: 10,
paddingBottom: 5,
},
headingFixed: {
fontSize: TITLE_TERTIARY,
fontWeight: 'bold',
color: COLOR_DARK_SECONDARY,
backgroundColor: 'transparent',
},
I will make use of Flex here.
Please note that i used borderWidth in the below example only for reference to show how it looks.
I will have flexDirection as row and i will give a flex: 1 to all the views inside
App.js
import React, { Component } from 'react';
import {
View,
Text
}
from 'react-native';
class App extends Component{
render(){
return(
<View>
<View style={styles.navBar}>
<View style={styles.itemStyle}>
<Text style={{fontSize: 18, color: 'blue'}}>Resumes</Text>
</View>
<View style={styles.itemStyle}>
<Text style={{fontSize: 20, color: 'blue'}}>Settings</Text>
</View>
<View style={styles.itemStyle}></View>
</View>
</View>
)
}
}
const styles = {
navBar: {
marginTop: 42,
height: 36,
flexDirection: 'row',
alignItems: 'center'
},
itemStyle: {
flex: 1,
height: 36,
alignItems: 'center',
justifyContent: 'center',
borderWidth: 1
}
}
export default App;
You can play around in the inside views. Move the buttonBack inside one of the child views.
I can think of two ways to accomplish this, but neither seems quite ideal.
The first way is using a transparent element with fixed width and justifyContent: 'space-between', as you indicated:
<View style={{flexDirection: 'row', justifyContent: 'space-between'}}>
<Text style={{width: 80}}>left</Text>
<Text>center</Text>
<Text style={{width: 80, color: 'transparent'}}>right</Text>
</View>
Setting a fixed width to the elements on each side will cause the middle element to center horizontally.
An alternative approach is using absolute styling. Using percentages with left and right requires React Native >= 0.42.
<View>
<Text>Left</Text>
<Text style={{position: 'absolute', width: 50, left: '50%', marginLeft: -25}}>Center</Text>
</View>

ReactNative: how to position Text-Elements one under another

I have to create a ListView having Rows which contains an Icon on the left and two text elements like so:
But what i get is this:
How to archieve this?
This is my render method for the row:
return (
<TouchableHighlight underlayColor='#dddddd'>
<View style={styles.container}>
<Icon
name='fontawesome|phone'
size={30}
color='gray'
style={styles.contactIcon}
/>
<Text style={styles.headline}>Anrufen</Text>
<Text style={styles.details}>{item.text}</Text>
<View style={styles.separator}/>
</View>
</TouchableHighlight>
);
And these are my styles:
container: {
flex: 1,
flexDirection: 'row',
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#F5FCFF',
padding: 15,
},
details: {
fontSize: 14,
marginBottom: 8
},
headline: {
fontSize: 18,
fontWeight: 'bold',
marginBottom: 8,
flex: 1
},
I tried to play with a width-statement for each text-element making it as wide as possible, nothing helped.
You have to wrap your both text-nodes in a parent-textnode giving style "flex=1" :
check this out:
<View style={{ flex: 1 }} >
<Text style={styles.headline}>Anrufen</Text>
<Text style={styles.details}>{item.text}</Text>
</View>
As an alternate solution, you could surround the two text elements with a view and then set its flex direction to column
<View style={{flex: 1, flexDirection: 'column'}}>
<Text style={styles.headline}>Anrufen</Text>
<Text style={styles.details}>{item.text}</Text>
</View>

Resources