React Native - how to make a border image? - css

I want to make a border image to a View , similar to border-image in the css.
How could I achieve it ?

I believe that if you use Styled Components (https://www.styled-components.com/) you can set it with CSS directly. It will be something like this:
import styled from 'styled-components/native';
const StyledView = styled.View`
border-image: <your definition here>;
`;
And then simply use it like you always do:
<StyledView>
</StyledView>
Hope it helps!

You can use ImageBackground component of react-native and wrap your view inside component by adding some padding around your nested view
<ImageBackground source={imageSource}>
<Text style={{padding:20}}> Inside </Text>
</ImageBackground>

I would go with an image that contains your border as the first element of your view and some padding on the contents of the view.
<Image
style={{
backgroundColor: '#ccc',
position: 'absolute',
width: '100%',
height: '100%',
justifyContent: 'center'
}}
source={{ uri: 'path/to/your/image/of/border' }}
>
<Text
style={{
backgroundColor: 'transparent',
textAlign: 'center',
fontSize: 30,
padding: 40,
}}
>
{text}
</Text>

Related

How can i move my button upside as the text is

I want my text and button at the top of the screen, but both the elements have a few gaps between, so I added marginBottom to my text and then that text went to the top. But I want that button to be at the top so I added marginBottom to the button too, but now it's not going to the top.
How can I position it to the top? Where is the style issue coming from? Please, explain my mistake as well.
import { StyleSheet, Text, View, Button } from 'react-native';
export default function App() {
return (
<View style={styles.container}>
<Text style={{ margin: 16, marginBottom: '80%', backgroundColor: 'black' }}>Hello World</Text>
<View style={{ marginBottom: '80%' }}>
<Button title='Click me' />
</View>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
},
});
You're using alignItems: 'center' and justifyContent: 'center'.
These two properties combined make the contents of container be positioned in the center. alignItems:center vertically centers the contents, and justifyContent:center horizontally centers the contents.
Since Text is the upper child element, giving it a marginBottom will space it out from the View element containing the Button. If you compare your screen with and without that marginBottom on the Text you'll notice that the button also moves slightly to the bottom if you include the marginBottom on the Text.
So in short, your code is doing exactly what you tell it to do: container tries to position all children to its center.
To fix this, you might want to remove the container:{ alignItems:'center', } property. This will most likely push all your elements to the top of the container. After that you might simply use marginTop on your Text element to push the contents down.
Change both marginBottom %80 to "auto".
return (
<View style={styles.container}>
<Text
style={{ margin: 16, marginBottom: "auto", backgroundColor: "white" }}
>
Hello World
</Text>
<View style={{ marginBottom: "auto" }}>
<Button title="Click me" />
</View>
</View>
);

StyleSheet /CSS : Placing Components in React Native

I am working on a React Native App . The components are vertically center as I desire but are all aligned on the bottom and can't get them move up towards the top of the screen.
Please take a look at the layout screen (attached here).
How can I get them to move up top?
Please Note : The yellow color in the screen is to figure out how far the component's view stretches.
I could not figure out to adjust the 'yellow' view. The 'yellow' view is only suppose to consist the donut/menu button .
<View style={styles.container}>
<TouchableOpacity style={styles.drawerButton} onPress={() => this.props.navigation.openDrawer()} >
<Image
source={menu}
style={{width: 25, height: 25, marginLeft: 5}}
/>
</TouchableOpacity>
<TextInput style={styles.addText} placeholder="Add New Item"/>
<Button style = {styles.submitButton} title = "Add" />
<TouchableOpacity style = {styles.pictureButton} onPress = {this.setCameraWindow}>
<Text style={{fontSize:14}}> Take Picture </Text>
</TouchableOpacity>
{this.state.isCameraVisible ? this.takePicture() : null }
</View>
);
}
}
const styles = StyleSheet.create ({
container:{
flex:1,
flexDirection: 'column',
alignItems:'center',
flexGrow: 1,
justifyContent: 'center',
backgroundColor: 'blue'
},
drawerButton:{
flex:1,
flexDirection:'row',
alignSelf:'flex-start',
backgroundColor:'yellow'
},
menuButton: {
height:50,
flex:1,
flexDirection:'column',
alignSelf:'flex-start',
backgroundColor:'yellow',
},
addText:{
flex:1,
flexDirection:'column',
justifyContent:'center',
backgroundColor:'white',
borderBottomColor: 'black',
borderBottomWidth: 2,
alignSelf:'center',
maxHeight:50,
},
submitButton:{
justifyContent:'center'
},
pictureButton:{
backgroundColor:'white',
justifyContent: 'center',
},
});
Thank you
You have given flex:1 inside the style={styles.drawerButton}, thats why its taking up the entire space and other things are pushed to the end of the screen, please remove flex:1 from that, and also remove justifyContent: 'center' from container style. Then all the content will be moved to the top
These styles are what you need. Specifically:
overflow: hidden: Hides the yellow bit when the menu is collapsed.
position: absolute on the menu. This means the menu will appear in the same position regardless of the other content. Use top: 10px; left: 10px to control the actual positioning of the menu.
position: relative on the menu's parent (TouchableOpacity) element. This means the position: absolute of the menu will be relative to the parent element.
You may have to get rid of some of the other styles, at least temporarily, so you can see what is happening.

Position an image inside of a View

I have a profile image in my header component and the source of it comes from database as a string array. What my problem is when i fetch user picture from database, it is slightly cutted from the top. So the head of user use looks like cutted. The image is in a view with borderRadius in order to make it circular.
What i tried:
resizeMode: 'cover',
resizeMode: 'contain',
position:'absolute',
bottom: 0,
and none of them are worked so far.
If you help me i will be appreciated,
thanks.
PS: i have looked several(more than 10) topics in stackoverflow and i could not make it.
Update
Here is my Header Component:
<View style={styles.container}>
<View style={styles.backButtonContainer} >
{isBackButtonIconVisible ? this._renderBackButtonIcon() : null}
</View>
<View style={styles.textContainer} >
<Text style={styles.text}>{text}</Text>
</View>
<View style={styles.profileButtonContainer}>
{isProfileIconVisible ? this._renderProfileIcon() : null}
{isProfilePictureVisible ? this._renderProfilePicture() : null}
</View>
</View>
Rendering Profile Picture:
_renderProfilePicture() {
let profileIcon = (
<View style={styles.profileButtonContainer} >
<CircularProfilePicture
onPress={this.props.onProfilePress}
ProfilePictureSourceUri={this.props.ProfilePictureSourceUri}
></CircularProfilePicture>
</View>
);
return profileIcon;
}
Here is my CircularProfilePicture component
class CircularProfilePicture extends Component {
render() {
const {onPress} = this.props;
return (
<View style={styles.container}>
<TouchableOpacity
onPress={() => onPress()}
>
<Image source={{ uri: 'data:image/png;base64,' + this.props.ProfilePictureSourceUri }}
style={styles.image} />
</TouchableOpacity>
</View>
)
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
borderRadius: 10,
},
image:{
width: 55,
height: 60,
alignSelf: 'center',
resizeMode: 'cover',
}
});
try this:
padding:3px; // putting your image in the middle of div, setting in px the
value you need
position:absolute;
width: 200px; // the value that you have designed your div
height: 200px; //the value that you have designed your div
border-radius:30%; // set the value you need;
-moz-border-radius: 30%; //ancient mozzila versions
-webkit-border-radius:30%; //ancient chrome or Safari versions
If I understand you correctly I think the style props alignItems and justifyContent might help you center the Image inside the View. Either that or position the View absolute and use flex: 1 on the Image to make it take upp all available space in the View.

Center a image and a text in a button in react native

I'd like to have a button with an image and a text centered.
The button is placed in the bottom of the screen.
I have this code :
<TouchableOpacity style={Styles.oneButton}>
<View style={Styles.oneButtonView}>
<Text style={Styles.payTextDollar}>
<Image
style={Styles.imageButton}
source={props.image}
/>
Pay
</Text>
</View>
</TouchableOpacity>
oneButton: {
height: 60,
backgroundColor: '#e41c23',
}
oneButtonView: {
flex: 1,
flexDirection: 'row',
alignItems: 'center',
height: 20,
justifyContent: 'center',
}
payTextDollar: {
flex: 1,
color: '#ffffff',
fontSize: 20,
fontFamily: 'MetaOffc-Light',
textAlign: 'center',
}
imageButton: {
marginTop: 6,
}
this works very well of iOS, however, the image is really small on Android, like so : https://i.stack.imgur.com/jFWAy.png
Do you know anything about this behaviour ?
Do you know if there's another solution to have the image and the text centered in the button like so : https://i.stack.imgur.com/geBSz.png
Thanks !
What are the styles you have set on your image?
Also you shouldn't have to nest image inside of text. I'd pull that out and put it before text.

React native text going off my screen, refusing to wrap. What to do?

The following code can be found in this live example
I've got the following react native element:
'use strict';
var React = require('react-native');
var {
AppRegistry,
StyleSheet,
Text,
View,
} = React;
var SampleApp = React.createClass({
render: function() {
return (
<View style={styles.container}>
<View style={styles.descriptionContainerVer}>
<View style={styles.descriptionContainerHor}>
<Text style={styles.descriptionText} numberOfLines={5} >
Here is a really long text that you can do nothing about, its gonna be long wether you like it or not, so be prepared for it to go off screen. Right? Right..!
</Text>
</View>
</View>
<View style={styles.descriptionContainerVer2}>
<View style={styles.descriptionContainerHor}>
<Text style={styles.descriptionText} numberOfLines={5} >Some other long text which you can still do nothing about.. Off the screen we go then.</Text>
</View>
</View>
</View>);
}
});
AppRegistry.registerComponent('SampleApp', () => SampleApp);
with the following styles:
var styles = StyleSheet.create({
container:{
flex:1,
flexDirection:'column',
justifyContent: 'flex-start',
backgroundColor: 'grey'
},
descriptionContainerVer:{
flex:0.5, //height (according to its parent)
flexDirection: 'column', //its children will be in a row
alignItems: 'center',
backgroundColor: 'blue',
// alignSelf: 'center',
},
descriptionContainerVer2:{
flex:0.5, //height (according to its parent)
flexDirection: 'column', //its children will be in a row
alignItems: 'center',
backgroundColor: 'orange',
// alignSelf: 'center',
},
descriptionContainerHor:{
//width: 200, //I DON\'T want this line here, because I need to support many screen sizes
flex: 0.3, //width (according to its parent)
flexDirection: 'column', //its children will be in a column
alignItems: 'center', //align items according to this parent (like setting self align on each item)
justifyContent: 'center',
flexWrap: 'wrap'
},
descriptionText: {
backgroundColor: 'green',//Colors.transparentColor,
fontSize: 16,
color: 'white',
textAlign: 'center',
flexWrap: 'wrap'
}
});
This results in the following screen:
How can I stop the text from going off the screen and keep it confined in the middle of the screen with a width of i.e. 80% of the parent.
I don't think I should use width because I will be running this on MANY different mobile screens and I want it to be dynamic, so I think I should rely totally on flexbox.
(That was the initial reason why I had flex: 0.8 within the descriptionContainerHor.
What I want to achieve is something like this:
Thank you!
I found solution from below link.
[Text] Text doesn't wrap #1438
<View style={{flexDirection:'row'}}>
<Text style={{flex: 1, flexWrap: 'wrap'}}> You miss fdddddd dddddddd
You miss fdd
</Text>
</View>
Below is the Github profile user link if you want to thank him.
Ally Rippley
Edit: Tue Apr 09 2019
As #sudoPlz mentioned in comments it works with flexShrink: 1 updating this answer.
The solution to that issue is flexShrink: 1.
<View
style={{ flexDirection: 'row' }}
>
<Text style={{ flexShrink: 1 }}>
Really really long text...
</Text>
</View>
Depending on your set up, you may also also need to add flexShrink: 1 to the <View>'s parent as well, to get this to work, so play with that and you'll make it.
The solution was discovered by Adam Pietrasiak in this thread.
This is a known bug. flexWrap: 'wrap' didn't work for me but this solution seems to work for most people
Code
<View style={styles.container}>
<Text>Some text</Text>
</View>
Styles
export default StyleSheet.create({
container: {
width: 0,
flexGrow: 1,
flex: 1,
}
});
you just need to have a wrapper for your <Text> with flex like below;
<View style={{ flex: 1 }}>
<Text>Your Text</Text>
</View>
This worked for me
<View style={{flexShrink:1}}>
<Text>some long random text...</Text>
</View>
Most of the times, we see this problem when using flexDirection: 'row' because in other case, it is handled properly.
Anyway, here are the two ways to wrap the text properly;
FIRST METHOD:
To wrap the text to next line and not leave the display, we can do so by restricting the width of the <Text>;
<Text style={{width: "60%"}}>some long text goes here ...</Text>
The above code will restrict the width of the text to 60% of the available width and if the whole text doesn't fit in that, it will wrap itself, i.e, remaining text will move to next line and so on.
SECOND METHOD
set flexShrink: 1 on both text element as well as its parent element which is wrapping it.
e.g,
<View style={{ flexShrink: 1, justifyContent: 'space-between', alignItems: 'center', flex: 1, flexDirection: 'row'}}>
<Text>First long string which goes long....</Text>
<Text style={{flexShrink: 1}}>This is a long long text which must go out of the screen if we dont style it properly and not do some logic here</Text>
</View>
Other styles are just to show that result is working properly. flexShrink: 1 is the only thing which you need.
Another solution that I found to this issue is by wrapping the Text inside a View. Also set the style of the View to flex: 1.
It works if you remove flexDirection: row from descriptionContainerVer and descriptionContainerVer2 respectively.
UPDATE (see comments)
I made a few changes to achieve what I think you're after. First of all I removed the descriptionContainerHor component. Then I set the flexDirection of the vertical views to row and added alignItems: 'center' and justifyContent: 'center'. Since the vertical views are now in fact stacked along the horizontal axis I removed the Ver part from the name.
So now you have a wrapper view that should vertically and horizontally align it's content and stack it along the x-axis. I then simply put two invisible View components on the left and right side of the Text component to do the padding.
Like this:
<View style={styles.descriptionContainer}>
<View style={styles.padding}/>
<Text style={styles.descriptionText} numberOfLines={5} >
Here is a really long text that you can do nothing about, its gonna be long wether you like it or not, so be prepared for it to go off screen. Right? Right..!
</Text>
<View style={styles.padding}/>
</View>
And this:
descriptionContainer:{
flex:0.5, //height (according to its parent),
flexDirection: 'row',
backgroundColor: 'blue',
alignItems: 'center',
justifyContent: 'center',
// alignSelf: 'center',
},
padding: {
flex: 0.1
},
descriptionText: {
backgroundColor: 'green',//Colors.transparentColor,
fontSize: 16,
flex: 0.8,
color: 'white',
textAlign: 'center',
flexWrap: 'wrap'
},
Then you get what I believe you were after.
FURTHER IMPROVEMENTS
Now if you would like to stack multiple text areas within the blue and orange views you can do something like this:
<View style={styles.descriptionContainer2}>
<View style={styles.padding}/>
<View style={styles.textWrap}>
<Text style={styles.descriptionText} numberOfLines={5} >
Some other long text which you can still do nothing about.. Off the screen we go then.
</Text>
<Text style={styles.descriptionText} numberOfLines={5} >
Another column of text.
</Text>
</View>
<View style={styles.padding}/>
</View>
Where textWrapis styled like this:
textWrap: {
flexDirection: 'column',
flex: 0.8
},
Hope this helps!
<View style={{flexDirection:'row'}}>
<Text style={{flex: 1, flexWrap: 'wrap'}}>
This will work
I had this same issue and to fix it I had to make sure ALL View parents had style={{flex: 1}}
I tried many of the answers above but none worked for me.
I achieved the best result by putting flexShrink on the Text element itself and flexGrow on both the parent View and the Text element.
I needed flexDirection: row on the parent because I want to have an icon on the right
<View style={flexDirection: 'row', flexGrow: 1}>
<Text style={
flexGrow: 1,
flexShrink: 1,
paddingLeft: 16,
paddingRight: 8,
alignItems: 'center',
}>
A long text that needs to wrap into multiple lines
</Text>
</View>
<Image source={rightArrow}/>
It looks like this:
In version 0.62.2 of React Native, i just put "flex-shrink: 1" in Container of my "Text", but remember the flex-direction:row in View of container. Thank you guys for the help.
My code:
export const Product = styled.View`
background: #fff;
padding: 15px 10px;
border-radius: 5px;
margin: 5px;
flex-direction: row;
`;
export const ProductTitleContainer = styled.View`
font-size: 16px;
margin-left: 5px;
flex-shrink: 1;
`;
export const ProductTitle = styled.Text`
font-size: 16px;
flex-wrap: wrap;
`;
`;
I wanted to add that I was having the same issue and flexWrap, flex:1 (in the text components), nothing flex was working for me.
Eventually, I set the width of my text components' wrapper to the width of the device and the text started wrapping.
const win = Dimensions.get('window');
<View style={{
flex: 1,
flexDirection: 'column',
justifyContent: 'center',
alignSelf: 'center',
width: win.width
}}>
<Text style={{ top: 0, alignSelf: 'center' }} >{image.title}</Text>
<Text style={{ alignSelf: 'center' }}>{image.description}</Text>
</View>
I think you can do something like this, I have attached a picture with code for a better idea:
So, we can do something like this:
TermsOfService = {
fontFamily: 'Verlag-Book';
fontSize: 14px;
textAlign: center;
},
HighlightedText = {
font-family: 'Verlag-Book';
font-size: 14px;
text-align: center;
color: ${COLORS.PRIMARY_ADMIRAL_BLUE};
},
Container: {
width: 100%;
alignSelf: center;
alignItems: center;
justifyContent: center;
flexDirection: row;
flexWrap: wrap;
}
And is your Component just use it like this:
<View style={Container}>
<Text style={TermsOfService}>By joining, you agree to the some thing </Text>
<Text style={HighlightedText}>this is highlighted </Text>
<Text style={TermsOfService}>and </Text>
<Text style={HighlightedText}>and this as well</Text>
</View>
<View style={{flexDirection:'row'}}>
<Text style={{ flex: number }}> You miss fdddddd dddddddd
You miss fdd
</Text>
</View>
{ flex: aNumber } is all you need!
Just set 'flex' to a number that suit for you. And then the text will wrap.
Non of the answers work for me, so I decided to use a hack, which is to split the text by whitespace and render each of the word separately.
Although it's a hack, the upside is that I don't have to worry so much about messing up the wrapping due to the parent's container style.
// This code is written in Typescript
import React from 'react'
import { StyleSheet, View, Text } from 'react-native'
const styles = StyleSheet.create({
container: {
display: 'flex',
flexWrap: 'wrap',
flexDirection: 'row',
flex: 1,
justifyContent: 'center',
paddingVertical: 8,
},
})
export const WrapText: React.FC<{
text: string
}> = ({ text }) => {
return (
<View style={styles.container}>
{text.split(' ').map((word, index) => (
<Text key={index}>
{word}{' '}
</Text>
))}
</View>
)
}
const Example = <WrapText text="Hello this is a working hack that wraps your text."/>
P/S: Of course this only works for alphabetical writing systems, other writing systems that does not utilise spaces (e.g. Chinese writings) will not wrap using this component.
Unfortunately none of the above worked for me.
I found this npm package you could use the package directly:
https://github.com/Bang9/react-native-wrapped-text
Or create something similar like this:
<View style={{ alignItems: "center", alignSelf: "center", width: "100%" }}>
<View style={{ flexDirection: "row", flexWrap: "wrap"}}>
<Text style={{ textAlign: "center"}}>Long text, sooo looong...</Text>
</View>
</View>
Based on :
https://github.com/Bang9/react-native-wrapped-text/blob/master/src/index.js
Use height: 'auto' in text style.
Tried everything nothing worked but this ->
wrapText:{
width:"65%"
},
listItemLeft:{
fontWeight:"bold",
margin:3
},
<View style={styles.wrapText}>
<Text style={styles.listItemLeft}>{item.left}</Text>
</View>
<SafeAreaView style={{flex:1}}>
<View style={{alignItems:'center'}}>
<Text style={{ textAlign:'center' }}>
This code will make your text centered even when there is a line-break
</Text>
</View>
</SafeAreaView>
try to use this prop adjustsFontSizeToFit={true} in text component like this.
<Text adjustsFontSizeToFit={true}>
my solution below:
<View style={style.aboutContent}>
<Text style={[styles.text,{textAlign:'justify'}]}>
// text here
</Text>
</View>
style:
aboutContent:{
flex:8,
width:widthDevice-40,
alignItems:'center'
},
text:{
fontSize:widthDevice*0.04,
color:'#fff',
fontFamily:'SairaSemiCondensed-Medium'
},
result:
[
<Text style={{width: 200}} numberOfLines={1} ellipsizeMode="tail">Your text here</Text>

Resources