React Native fixed footer - javascript

I try to create react native app that looks like existing web app. I have a fixed footer at bottom of window. Do anyone have idea how this can be achieved with react native?
in existing app it's simple:
.footer {
position: fixed;
bottom: 0;
}

Here's the actual code based on Colin's Ramsay answer:
<View style={{flex: 1}}>
<ScrollView>main</ScrollView>
<View><Text>footer</Text></View>
</View>

Off the top of my head you could do this with a ScrollView. Your top-level container could be a flex container, inside that have a ScrollView at the top and your footer at the bottom. Then inside the ScrollView just put the rest of your app as normal.

I'm using fixed footers for buttons in my app. The way I implement a fixed footer is like so:
<View style={{flex: 1}}>
<View><Text>my text</Text></View>
<View style={{position: 'absolute', left: 0, right: 0, bottom: 0}}><Text>My fixed footer</Text></View>
</View>
And if need the footer to move up when a keyboard appears for instance you can use:
const { DeviceEventEmitter } = React
class MyClass {
constructor() {
this.state = {
btnLocation: 0
}
}
componentWillMount() {
DeviceEventEmitter.addListener('keyboardWillShow', this.keyboardWillShow.bind(this))
DeviceEventEmitter.addListener('keyboardWillHide', this.keyboardWillHide.bind(this))
}
keyboardWillShow(e) {
this.setState({btnLocation: e.endCoordinates.height})
}
keyboardWillHide(e) {
this.setState({btnLocation: 0})
}
}
Then use {bottom: this.state.btnLocation} in your fixed footer class. I hope this helps!

You get the Dimension first and then manipulate it through flex style
var Dimensions = require('Dimensions')
var {width, height} = Dimensions.get('window')
In render
<View style={{flex: 1}}>
<View style={{width: width, height: height - 200}}>main</View>
<View style={{width: width, height: 200}}>footer</View>
</View>
The other method is to use flex
<View style={{flex: 1}}>
<View style={{flex: .8}}>main</View>
<View style={{flex: .2}}>footer</View>
</View>

#Alexander Thanks for solution
Below is code exactly what you looking for
import React, {PropTypes,} from 'react';
import {View, Text, StyleSheet,TouchableHighlight,ScrollView,Image, Component, AppRegistry} from "react-native";
class mainview extends React.Component {
constructor(props) {
super(props);
}
render() {
return(
<View style={styles.mainviewStyle}>
<ContainerView/>
<View style={styles.footer}>
<TouchableHighlight style={styles.bottomButtons}>
<Text style={styles.footerText}>A</Text>
</TouchableHighlight>
<TouchableHighlight style={styles.bottomButtons}>
<Text style={styles.footerText}>B</Text>
</TouchableHighlight>
</View>
</View>
);
}
}
class ContainerView extends React.Component {
constructor(props) {
super(props);
}
render() {
return(
<ScrollView style = {styles.scrollViewStyle}>
<View>
<Text style={styles.textStyle}> Example for ScrollView and Fixed Footer</Text>
</View>
</ScrollView>
);
}
}
var styles = StyleSheet.create({
mainviewStyle: {
flex: 1,
flexDirection: 'column',
},
footer: {
position: 'absolute',
flex:0.1,
left: 0,
right: 0,
bottom: -10,
backgroundColor:'green',
flexDirection:'row',
height:80,
alignItems:'center',
},
bottomButtons: {
alignItems:'center',
justifyContent: 'center',
flex:1,
},
footerText: {
color:'white',
fontWeight:'bold',
alignItems:'center',
fontSize:18,
},
textStyle: {
alignSelf: 'center',
color: 'orange'
},
scrollViewStyle: {
borderWidth: 2,
borderColor: 'blue'
}
});
AppRegistry.registerComponent('TRYAPP', () => mainview) //Entry Point and Root Component of The App
Below is the Screenshot

Simple stuff here:
Incase you don't need a ScrollView for this approach you can go with the below code to achieve Something like this :
<View style={{flex: 1, backgroundColor:'grey'}}>
<View style={{flex: 1, backgroundColor: 'red'}} />
<View style={{height: 100, backgroundColor: 'green'}} />
</View>

You might also want to take a look at NativeBase (http://nativebase.io). This a library of components for React Native that include some nice layout structure (http://nativebase.io/docs/v2.0.0/components#anatomy) including Headers and Footers.
It's a bit like Bootstrap for Mobile.

The way I did this was to have a view (lets call it P) with flex 1, then inside that view have 2 more views (C1 and C2) with flex 0.9 and 0.1 respectively (you can change the flex heights to required values). Then, inside the C1 have a scrollview. This worked perfectly for me. Example below.
<View style={{flex: 1}}>
<View style={{flex: 0.9}}>
<ScrollView>
<Text style={{marginBottom: 500}}>scrollable section</Text>
</ScrollView>
</View>
<View style={{flex: 0.1}}>
<Text>fixed footer</Text>
</View>
</View>

Below is code to set footer and elements above.
import React, { Component } from 'react';
import { StyleSheet, View, Text, ScrollView } from 'react-native';
export default class App extends Component {
render() {
return (
<View style={styles.containerMain}>
<ScrollView>
<Text> Main Content Here</Text>
<Text> Main Content Here</Text>
<Text> Main Content Here</Text>
<Text> Main Content Here</Text>
<Text> Main Content Here</Text>
<Text> Main Content Here</Text>
<Text> Main Content Here</Text>
<Text> Main Content Here</Text>
<Text> Main Content Here</Text>
<Text> Main Content Here</Text>
<Text> Main Content Here</Text>
<Text> Main Content Here</Text>
<Text> Main Content Here</Text>
<Text> Main Content Here</Text>
<Text> Main Content Here</Text>
<Text> Main Content Here</Text>
<Text> Main Content Here</Text>
<Text> Main Content Here</Text>
<Text> Main Content Here</Text>
<Text> Main Content Here</Text>
<Text> Main Content Here</Text>
<Text> Main Content Here</Text>
<Text> Main Content Here</Text>
<Text> Main Content Here</Text>
<Text> Main Content Here</Text>
<Text> Main Content Here</Text>
<Text> Main Content Here</Text>
<Text> Main Content Here</Text>
<Text> Main Content Here</Text>
<Text> Main Content Here</Text>
<Text> Main Content Here</Text>
<Text> Main Content Here</Text>
<Text> Main Content Here</Text>
<Text> Main Content Here</Text>
<Text> Main Content Here</Text>
<Text> Main Content Here</Text>
<Text> Main Content Here</Text>
<Text> Main Content Here</Text>
<Text> Main Content Here</Text>
<Text> Main Content Here</Text>
<Text> Main Content Here</Text>
<Text> Main Content Here</Text>
<Text> Main Content Here</Text>
<Text> Main Content Here</Text>
<Text> Main Content Here</Text>
<Text> Main Content Here</Text>
<Text> Main Content Here</Text>
<Text> Main Content Here</Text>
<Text> Main Content Here</Text>
<Text> Main Content Here</Text>
<Text> Main Content Here</Text>
<Text> Main Content Here</Text>
<Text> Main Content Here</Text>
<Text> Main Content Here</Text>
<Text> Main Content Here</Text>
<Text> Main Content Here</Text>
<Text> Main Content Here</Text>
<Text> Main Content Here</Text>
<Text> Main Content Here</Text>
<Text> Main Content Here</Text>
<Text> Main Content Here</Text>
<Text> Main Content Here</Text>
<Text> Main Content Here</Text>
<Text> Main Content Here</Text>
<Text> Main Content Here</Text>
</ScrollView>
<View style={styles.bottomView}>
<Text style={styles.textStyle}>Bottom View</Text>
</View>
</View>
);
}
}
const styles = StyleSheet.create({
containerMain: {
flex: 1,
alignItems: 'center',
},
bottomView: {
width: '100%',
height: 50,
backgroundColor: '#EE5407',
justifyContent: 'center',
alignItems: 'center',
position: 'absolute',
bottom: 0,
},
textStyle: {
color: '#fff',
fontSize: 18,
},
});

When flex is a positive number, it makes the component flexible and it will be sized proportional to its flex value. So a component with flex set to 2 will take twice the space as a component with flex set to 1.
<View style={{flex: 1}>
<ScrollView style={{flex: 1}>
//your scroll able content will be placed above your fixed footer content.
//when your content will grow bigger and bigger it will hide behind
//footer content.
</ScrollView>
<View style={styles.footerContainer}>
//your fixed footer content will sit fixed below your screen
</View>
</View>

One could achieve something similar in react native with position: absolute
let footerStyle = {
position: 'absolute',
bottom: 0,
}
There are a few things to keep in mind though.
absolute positions the element relative to its parent.
You might have to set the width and hight of the element manually.
Width and hight will change when orientation changes. This has to be managed manually
A practical style definition would look something like this:
import { Dimensions } from 'react-native';
var screenWidth = Dimensions.get('window').width; //full screen width
let footerStyle = {
position: 'absolute',
bottom: 0,
width: screenWidth,
height: 60
}

Suggestion 1
=> Body with fixed footer
<View style={{ flex: 1, backgroundColor: 'gray' }}>
<View style={{ flex: 9, backgroundColor: 'gray',alignItems: 'center', justifyContent: 'center', }}>
<Text style={{color:'white'}}>...Header or Body</Text>
</View>
<View style={{ flex: 1, backgroundColor: 'yellow', alignItems: 'center', justifyContent: 'center', }}>
<Text>...Footer</Text>
</View>
</View>
Edit 2
=> Body & Fixed footer with tabs
<View style={{ flex: 1, backgroundColor: 'gray' }}>
<View style={{ flex: 9, backgroundColor: 'gray', alignItems: 'center', justifyContent: 'center', }}>
<Text style={{ color: 'white' }}>...Header or Body</Text>
</View>
<View style={{ flex: 1, backgroundColor: 'yellow', alignItems: 'center', justifyContent: 'center', }}>
<View style={{ flex: 1, flexDirection: 'row' }}>
<TouchableOpacity style={{ flex: 1, alignItems: 'center', justifyContent: 'center', backgroundColor: 'white' }}>
<View>
<Text>
...Home
</Text>
</View>
</TouchableOpacity>
<TouchableOpacity style={{ flex: 1, alignItems: 'center', justifyContent: 'center', backgroundColor: 'white' }}>
<View>
<Text>
...Settings
</Text>
</View>
</TouchableOpacity>
</View>
</View>
</View>
Notes
import {TouchableOpacity} from 'react-native'
Advantages
We can use this simple footer without react bottom navigation

The best way is to use justifyContent property
<View style={{flexDirection:'column',justifyContent:'flex-end'}}>
<View>
<Text>fixed footer</Text>
</View>
</View>
if you have multiple view elements on screen, then you can use
<View style={{flexDirection:'column',justifyContent:'space-between'}}>
<View>
<Text>view 1</Text>
</View>
<View>
<Text>view 2</Text>
</View>
<View>
<Text>fixed footer</Text>
</View>
</View>

I found using flex to be the simplest solution.
<View style={{flex:1,
justifyContent: 'space-around',
alignItems: 'center',
flexDirection: 'row',}}>
<View style={{flex:8}}>
//Main Activity
</View>
<View style={{flex:1}}>
//Footer
</View>
</View>

import {Dimensions} from 'react-native'
const WIDTH = Dimensions.get('window').width;
const HEIGHT = Dimensions.get('window').height;
then on the write this styles
position: 'absolute',
top: HEIGHT-80,
left: 0,
right: 0,
worked like a charm

if you just use react native so you can use the following code
<View style={{flex:1}}>
{/* Your Main Content*/}
<View style={{flex:3}}>
<ScrollView>
{/* Your List View ,etc */}
</ScrollView>
</View>
{/* Your Footer */}
<View style={{flex:1}}>
{/*Elements*/}
</View>
</View>
also, you can use https://docs.nativebase.io/ in your react native project and then do something like the following
<Container>
{/*Your Main Content*/}
<Content>
<ScrollView>
{/* Your List View ,etc */}
</ScrollView>
</Content>
{/*Your Footer*/}
<Footer>
{/*Elements*/}
</Footer>
</Container>
React_Native
NativeBase.io

For Android problems with this:
in app/src/AndroidManifest.xml change windowSoftInputMode to the following.
<activity
android:windowSoftInputMode="stateAlwaysHidden|adjustPan">
I had absolutely no problems with this in ios using react-native and keyboardAwareScroll. I was about to implement a ton of code to figure this out until someone gave me this solution. Worked perfectly.

Set android:windowSoftInputMode="adjustPan" in your manifest file, and it will work as you expect.

I've used a combination of height: 100% and flex: 1.
<View style={{ height: "100%" }}>
<View
style={{
display: "flex",
flexDirection: "row",
alignItems: "center",
height: 50,
}}
>
{R.map(
tab => (
<TouchableOpacity
key={tab.id}
onPress={() => setCurrentTab(tab)}
>
<Text>{tab.name}</Text>
</TouchableOpacity>
),
tabs
)}
</View>
<View style={{ flex: 1 }}>
<View style={{ height: "100%" }}>
<View style={{ flex: 1 }}>
<ScrollView
style={{
width: "100%",
}}
>
... ScrollView content
</ScrollView>
</View>
<View
style={{
borderTopColor: "#dadada",
borderTopWidth: 1,
width: "100%",
alignItems: "center",
justifyContent: "center",
height: 60,
paddingBottom: 10,
}}
>
<TouchableOpacity
style={{
padding: 8,
borderRadius: 3,
}}
>
<Text>
Show Results
</Text>
</TouchableOpacity>
</View>
</View>
</View>

I think best and easy one would be as below, just place rest of ur view in a content and footer in a separate view.
`<Container>
<Content>
<View>
Ur contents
</View>
</Content>
<View>
Footer
</View>
</Container>`
or u can use footer from native-base
`<Container>
<Content>
<View>
Ur contents
</View>
</Content>
<Footer>
Footer
</Footer>
</Container>`

i created a package. it may meet your needs.
https://github.com/caoyongfeng0214/rn-overlaye
<View style={{paddingBottom:100}}>
<View> ...... </View>
<Overlay style={{left:0, right:0, bottom:0}}>
<View><Text>Footer</Text></View>
</Overlay>
</View>

Create a Style like this:
const styles = StyleSheet.create({
header:{ backgroundColor: "#00BFFF", height: "20%" },
footer:{ backgroundColor: "royalblue", height: "10%", flexDirection: "row", alignItems: "center" }
});
Then use the style in a tag :
<View style={styles.footer}>
<View style={{ flex: 1, alignItems: "center" }}>
<Pressable onPress={() => openCamera(true)}>
<View style={{ flexDirection: "column", alignItems: "center" }}>
<Icon name="camera" style={{ fontSize: 21, color: "white" }}/>
<Text style={{ color: "white" }}>Photo</Text>
</View>
</Pressable>
</View>
</View>

Related

is there way to put text "cancel" and "ok" below the avatar buttons ? i mean that the avatar and the text need to be pressable when click

is there a way to put the text "cancel" and "ok" below the avatar button? I mean that the avatar and the text need to be pressable when click.
I can't put the text below to every button and I don't understand what is my mistake.
this is what I get now
but I need the text below to every button and also must be also pressable same the image (it should be part of the button)
this is my example of code :
const OrderInformationScreen = props => {
return (
<View
style={{
backgroundColor: '#00BFFF',
alignItems: 'flex-start',
justifyContent: 'center',
marginTop: 30,
borderBottomWidth: 2,
borderColor: 'blue',
flexDirection: "row",
justifyContent: 'space-evenly'
}}
>
<Avatar
size='large'
containerStyle={{ marginTop: 30 }}
activeOpacity={0.2}
rounded
source={require('../assets/down.png')} style={{ height: 80, width: 80 }}
onPress={() => console.log("cancel!")}
/>
<View >
<Text style={{ fontSize: 30 }}>cancel</Text>
</View>
<Avatar
size='large'
activeOpacity={0.2}
rounded
source={require('../assets/up.png')} style={{ height: 80, width: 80 }}
onPress={() => console.log("Works!")}
/>
<View>
<Text style={{ fontSize: 30 }}>ok</Text>
</View>
</View>
);
};
I think the best option is wrapping the avatar and the text by TouchableOpacity.
<TouchableOpacity onPress={() => console.log("cancel!")}>
<Avatar
size='large'
containerStyle={{ marginTop: 30 }}
activeOpacity={0.2}
rounded
source={require('../assets/down.png')} style={{ height: 80, width: 80 }}
/>
<View >
<Text style={{ fontSize: 30 }}>cancel</Text>
</View>
</TouchableOpacity>
I recommend to write your own styles by using basic react native elements. Try to use least number of 3rd party plugins. Good luck.
It is like that because of the styles you have given to view. You have given a flex direction row which will place all your elements in a row. You have given four elements in your root view which has style flex-direction row so all four elements in that view (2 Avatar component and 2 text) will be placed side by side in a row.
if you want text below image i thin you should put avatar and text box in a view and give that a view a flex-direction column like:
<View style={{flexDirection: 'row', justifyContent: 'space-evenly'}}>
<TouchableOpacity onPress={() => console.log("cancel!")>
<View style={{flexDirection: 'column', justifyContent: 'space-evenly'}}>
<Avatar>
<View>
<Text />
</View>
<View>
</TouchableOpacity>
<TouchableOpacity onPress={() => console.log("works!")>
<View style={{flexDirection: 'column', justifyContent: 'space-evenly'}}>
<Avatar>
<View>
<Text />
</View>
<View>
</TouchableOpacity>
<View>
hope this helps in someway :)
The best option is Wrapping the avatar and text with TouchableOpacity. and Add some more Styles like below
<TouchableOpacity style={{
backgroundColor: '#00BFFF',
display : "flex",
alignItems: 'flex-start',
justifyContent: 'center',
marginTop: 30,
borderBottomWidth: 2,
borderColor: 'blue',
}} onPress={() => {}>
<Avatar
size='large'
containerStyle={{ marginTop: 30 }}
activeOpacity={0.2}
rounded
source={require('../assets/down.png')} style={{ height: 80, width: 80 }}
/>
<View >
<Text style={{ fontSize: 30 }}>cancel || ok</Text>
</View>
</TouchableOpacity>

How to have two centered and clickable image link in react-native

I want to have the two images clickable next to each over, this is my view:
function MyView(props) {
return (
<View style={{ flex: 1, }}>
<View style={{
// width: 230,
flex: 1,
justifyContent: 'center',
alignItems: 'center',
}}>
<ExternalLink href="https://play.google.com/store/apps/details">
<Image
source={availableAtGooglePlayImage}
style={{
width: '100%',
height: 70,
flex: 1,
marginTop: 10,
resizeMode: 'contain',
}}
/>
</ExternalLink>
</View>
<View style={{
// width: 230,
flex: 1,
justifyContent: 'center',
alignItems: 'center',
}}>
<ExternalLink href="https://itunes.apple.com/fr/app">
<Image
resizeMode="stretch"
source={availableAtAppStoreImage}
style={{
width: '100%',
height: 70,
flex: 1,
marginTop: 10,
resizeMode: 'contain',
}}
/>
</ExternalLink>
</View>
);
}
As soon as I use flex: 1 on the parent view of ExternalLink, the image disappear.
I have not found a way to get those two images next to each over.
I have only find a way to have them on top of each over, and the whole width is clickable but I want only the image to be clickable.
How this is possible in react-native ?
Can you check this code please, this is a working example expo :
import * as React from 'react';
import { Text, View, StyleSheet ,Image,TouchableOpacity,Linking } from 'react-native';
export default class App extends React.Component {
render() {
return (
<View style={styles.container}>
<View>
<TouchableOpacity onPress={() =>Linking.openURL("https://play.google.com/store/apps/details")}>
<Image style={{height:50,width:50}} source={{uri:"https://source.unsplash.com/random"}} />
</TouchableOpacity>
</View>
<View>
<TouchableOpacity onPress={() =>Linking.openURL("https://itunes.apple.com/fr/app")}>
<Image style={{height:50,width:50}} source={{uri:"https://source.unsplash.com/random"}} />
</TouchableOpacity>
</View>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
flexDirection:'row',
justifyContent:'space-around',
alignItems:'center',
},
});
Feel free for doubts
What you are looking for is {flexDirection: 'row'} property in style.
Copy code to https://snack.expo.io/
import * as React from 'react';
import { Text, View, StyleSheet, TouchableOpacity, Image, Linking } from 'react-native';
export default class App extends React.Component {
render() {
return (
<>
<View style={{flex:1, flexDirection:'row'}}>
<TouchableOpacity
style={styles.imageButton}
onPress={() =>{Linking.openURL("https://play.google.com/store/apps/details")}}
>
<Image
resizeMode={'contain'}
style={styles.coverImage}
source={{uri: 'https://facebook.github.io/react/logo-og.png'}}
/>
</TouchableOpacity>
<TouchableOpacity
style={styles.imageButton}
onPress={() =>{Linking.openURL("https://itunes.apple.com/fr/app")}}
>
<Image
resizeMode={'contain'}
style={styles.coverImage}
source={{uri: 'https://facebook.github.io/react/logo-og.png'}}
/>
</TouchableOpacity>
</View>
</>
);
}
}
const styles = StyleSheet.create({
coverImage: {
flex: 1,
alignSelf: 'stretch',
width: undefined,
height: undefined
},
imageButton:{
flex:1,
height:70
}
});

Vertically align items in the center inside flew direction row

I have some icon buttons inside a view which is pushed to the right of the container by flex direction row on the parent. Currently I cannot align them vertically in the middle of the container. Here is the code I have:
JSX:
<View style={styles.groupContainer}>
<View style={styles.groupTextContainer}>
<Text style={styles.groupText}>{title.toUpperCase()}</Text>
</View>
<View style={styles.groupButtonsContainer}>
<Icon
key={name + type}
onPress={onPress}
style={{marginLeft: 8}}
name={name}
type={type}
color='silver' />
<Icon
key={name + type}
onPress={onPress}
style={{marginLeft: 8}}
name={name}
type={type}
color='silver' />
</View>
</View>
styles:
groupContainer: {
backgroundColor: '#ddd',
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'space-between',
},
groupText: {
fontWeight: 'bold',
color: '#808080',
},
groupTextContainer: {
padding: 10,
alignSelf: 'flex-start',
},
groupButtonsContainer: {
alignSelf: 'flex-end',
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'center',
}
UPDATE
Forgot to mention that Icon is a react-native-elements component.
I need it to look like this:
But I get this:
<View style={styles.groupContainer}>
<View style={styles.groupButtonsContainer}>
<Text style={styles.groupText}>{title.toUpperCase()}</Text>
<Icon
key={name + type}
onPress={onPress}
style={{marginLeft: 8}}
name={name}
type={type}
color='silver' />
</View>
</View>
mybe you can follow this code and you restyle from text

React Native: Why don't flex justifyContent and alignItems work for child <View/>?

In React Native, I have a child view inside another view, but it doesn't center in the middle of the page. But if the child view is not inside the parent view and alone, it centers fine in the middle of page.
How can I make it so that the child view centers to the middle of the page while being inside another view (parentView)?
Here is the code:
render() {
return (
<View id="parentView">
<View
id="childView"
style={
flex: 1,
justifyContent: 'center',
alignItems: 'center',
}
>
<Text>Center This to Middle of Page</Text>
</View>
<View
id="childViewTwo"
>
<Text>Don't center me</Text>
</View>
</View>
);
}
Just add flex:1 to your parent View. I made a working example for you:
https://rnplay.org/apps/zHO1YA
return (
<View id="parentView" style={{flex: 1}}>
<View
id="childView"
style={{
flex: 1,
justifyContent: 'center',
alignItems: 'center',
}}
>
<Text>Center This to Middle of Page</Text>
</View>
<View
id="childViewTwo"
>
<Text>Don't center me</Text>
</View>
</View>
);

React-native view auto width by text inside

As far as I know, react-native stylesheet doesn't supports min-width/max-width property.
I have a view and text inside. The view in auto width doesn't resize by inherit text element.
How to fix that issue and make view width automatically set using text width?
My code is:
<View style={{backgroundColor: '#000000'}}>
<Text style={{color: '#ffffff'}}>Sample text here</Text>
</View>
In common HTML/CSS I would realize so:
<div style="background-color: #000; display: inline;">Sample text here</div>
Notice: flex: 1 on parent view is not helpful for me.
Text appears as
"Sam"
"ple"
"Tex"
"t"
"alignSelf" does the same as 'display: inline-block' would in common HTML/CSS and it works very well for me.
<View style={{backgroundColor: '#000000', alignSelf: 'flex-start' }}>
<Text style={{color: '#ffffff'}}>
Sample text here
</Text>
</View>
Two Solutions
Text component fits the text content
https://facebook.github.io/react-native/docs/text.html#containers
You can wrap <Text> components into another <Text> component.
By doing this everything inside is no longer using the flexbox layout but using text layout.
<Text>
<Text>{'Your text here'}</Text>
</Text>
View container adapt to nested Text component's content
In that case you need to use the props alignSelf in order to see the container shrink to the size of its content.
<View>
<View style={{ alignSelf: 'center', padding: 12}} >
<Text>{'Your text here'}</Text>
</View>
</View>
tldr: set alignItems to any value other than 'stretch' for the style of the parent View of your View containing Text
The issue your facing is likely related to React Native's default value for alignItems: 'stretch' on a <View /> element. Basically, all <View /> elements by default cause their children to stretch along the cross axis (axis opposite to the flexDirection). Setting alignItems to any value other than "stretch" ("baseline", "flex-start", "flex-end", or "center") on the parent View prevents this behavior and addresses your problem.
Below is an example where there are two View elements contained inside of a parent View with a blue border. The two View elements each contain a View wrapped around a Text element. In the case of the first View with default styling, the yellow child View expands horizontally to fill the entire width. In the second View where alignItems: 'baseline', the pink View does not expand and stays the size of it's child Text element.
<View style={{ borderWidth: 5, borderColor: 'blue' }}>
<View>
<View style={{ backgroundColor: 'yellow' }}>
<Text style={{ fontSize: 30 }}>Hello</Text>
</View>
</View>
<View style={{ alignItems: 'baseline' }}>
<View style={{ backgroundColor: 'pink' }}>
<Text style={{ fontSize: 30 }}>Hello</Text>
</View>
</View>
</View>
The align-items property is explained well here.
If you want to apply width to View based on <Text> , you can do something like this :
<View style={styles.container}>
<Text>
{text}
</Text>
</View>
const styles = StyleSheet.create({
container: {
flexDirection:"row",
alignSelf:"flex-start",
paddingTop: Constants.statusBarHeight,
backgroundColor: '#ecf0f1',
padding: 8,
}
});
WORKING DEMO
This work for me.
<View style={{alignSelf: 'flex-start', backgroundColor: 'red'}}>
<Text>abc</Text>
</View>
Or simply:
<Text style={{color: '#ffffff', alignSelf: 'center'}}>Sample text here</Text>
Try this way for your requirement:
Here my height is Constant and i am enlarging the width by the length of text.
<View style={{flexDirection: 'row'}}>
<View style={{
height: 30, width: 'auto', justifyContent:'center',
alignItems: 'center'}}>
<Text style={{color:'white'}}>Now View will enlarge byitself</Text>
</View>
</View>
For Both Height and Width Try Changing the height inside the View style to 'auto' full code bellow:
<View style={{flexDirection: 'row'}}>
<View style={{
height: 'auto', width: 'auto', justifyContent:'center',
alignItems: 'center'}}>
<Text style={{color:'white'}}>Now View will enlarge byitself</Text>
</View>
</View>
Also try Giving padding to the View for arrange the text properly.
It works with Nicholas answer unless you want to center the view somewhere. In that case, you could add a wrapper view around the view to obtain the width of its content and set alignItems: 'center'. Like this:
<View style={{ flex: 1, alignItems: 'center' }}>
<View style={{ justifyContent: 'center', alignItems: 'center', backgroundColor: 'red' }}>
<Text>{'Your text is here'}</Text>
</View>
</View>
The background color is added to show the size of the inner view
Just add alignSelf to the text style, it won't take the whole width
<View style={{flex: 1}}>
<Text style={{alignSelf: 'center'}}>{'Your text here'}</Text>
<Text style={{alignSelf: 'baseline'}}>{'Your text here'}</Text>
<Text style={{alignSelf: 'flex-end'}}>{'Your text here'}</Text>
<Text style={{alignSelf: 'flex-start'}}>{'Your text here'}</Text>
</View>
These worked for me
<View style={styles.imageCancel}>
<TouchableOpacity onPress={() => { this.setModalVisible(!this.state.visible) }}>
<Text style={styles.textCancel} >Close</Text>
</TouchableOpacity>
</View>
const styles = StyleSheet.create({
imageCancel: {
height: 'auto',
width: 'auto',
justifyContent:'center',
backgroundColor: '#000000',
alignItems: 'flex-end',
},
textCancel: {
paddingTop:25,
paddingRight:25,
fontSize : 18,
color : "#ffffff",
height: 50,
},
}};

Categories

Resources