I'm trying to make a bottom navbar in React Native but it isn't spanning the full width, only the width of its content. I have tried using vw as in How to use vw and vh css with React Native but it gives the error: "width":<> is not usable as native method argument.
AppBar:
import { View, Pressable, Text } from "react-native"
const AppBar = ({ style, addNote }) => {
return (
<View style={style}>
<Pressable
onPress={() => addNote({ id: "9", title: "Hii", body: "new note" })}
>
<Text style={{ textAlign: "center", fontSize: 30 }}>Add</Text>
</Pressable>
</View>
)
}
export default AppBar
style:
appbar: {
position: "absolute",
bottom: 0,
display: "flex",
justifyContent: "center",
flexGrow: 1,
flexShrink: 1,
marginRight: "auto",
},
How can I get the AppBar to span the full width?
Related
How do you align items to the left and the right in React Native?
Whatever combination of flexbox properties I try, the two sets of text are stuck next to each other like this:
How do you make it so "Sign In" is on the right side of the screen and Repositories on the left?
Here is my code:
import { View, StyleSheet, Text, ScrollView } from 'react-native';
import Constants from 'expo-constants';
import { Link } from "react-router-native";
const styles = StyleSheet.create({
container: {
paddingTop: Constants.statusBarHeight,
paddingLeft: 10,
paddingBottom: 20,
backgroundColor: 'grey',
},
text: {
fontSize: 20,
color: 'white',
fontWeight: 'bold'
},
linkText: {
color: 'white',
},
nesteddivleft: {
flex: 1,
display: "flex",
justifyContent: "flex-start",
alignItems: "center",
},
nesteddivright: {
flex: 1,
display: "flex",
justifyContent: "flex-end",
alignItems: "center",
},
scrollbar: {
display: 'flex',
justifyContent: 'space-between'
}
});
const AppBar = () => {
return <><View style={styles.container}>
<ScrollView style="scrollview" horizontal>
<View style={styles.nesteddivleft}><Link to="/"><Text style={styles.text}>Repositories</Text></Link></View>
<View style={styles.nesteddivright}><Link to="/signin"><Text style={styles.linkText}>Sign In</Text></Link></View>
</ScrollView>
</View>
</>
};
export default AppBar;
App:
import Main from './src/components/Main'
import { StatusBar } from 'expo-status-bar';
import { NativeRouter } from 'react-router-native';
export default function App() {
return (
<>
<NativeRouter>
<Main/>
</NativeRouter>
<StatusBar style="auto" />
</>
);
}
As you can see, I have tried putting justify-content: space-between on the parent div and that does nothing.
I also tried this solution and it has done nothing: Aligning elements left, center and right in flexbox
import { View, StyleSheet, Text, ScrollView } from 'react-native';
import Constants from 'expo-constants';
import { Link } from "react-router-native";
const styles = StyleSheet.create({
container: {
paddingTop: Constants.statusBarHeight,
paddingLeft: 10,
paddingBottom: 20,
backgroundColor: 'grey',
display: "flex",
justifyContent: "space-between",
minWidth: '100%',
flexDirection: "row"
},
text: {
fontSize: 20,
color: 'white',
fontWeight: 'bold'
},
linkText: {
color: 'white',
},
nesteddivleft: {
},
nesteddivright: {
},
scrollbar: {
}
});
const AppBar = () => {
return <><View style={styles.container}>
<View style={styles.nesteddivleft}><Link to="/"><Text style={styles.text}>Repositories</Text></Link></View>
<View style={styles.nesteddivright}><Link to="/signin"><Text style={styles.linkText}>Sign In</Text></Link></View>
</View>
</>
};
export default AppBar;
Steps to solve issue:
Take out the scrollview component.
set Display to flex, justify Content to space-between, minWidth to 100% AND flex Direction to Row in parent component.
Not optimal as I need the Scrollview component in there as well, I will need to find a solution that allows me to have that component as a child.
I have written following code but my flex under 'titleContainer' is not working.
export const Focus = () => {
return (
<View style={styles.container}>
<View style={styles.titleContainer}>
<Text style={styles.title}>What would you like to focus on?</Text>
<TextInput />
</View>
</View>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#43840',
},
titleContainer: {
flex: 0.5,
padding: 16,
justifyContent: 'center',
backgroundColor: '#559974',
},
title: {
color: 'white',
fontWeight: 'bold',
fontSize: 15,
},
});
Please see the screen shot. The green background should cover half of the screen.
Its resolved now!
Actually this component was getting displayed conditionally. There was an issue with that condition. I have fixed that and everything worked.
Flex in RN only take interger value
In case you want titleContainer take 50% size of container by using flex, This is how you can achieve that.
You need another view the take the same flex value with titleContainer, so titleContainer and that dump view will take 50% size of parent view each
export const Focus = () => {
return (
<View style={styles.container}>
<View style={styles.titleContainer}>
<Text style={styles.title}>What would you like to focus on?</Text>
<TextInput />
</View>
<View style={{flex: 1}} />
</View>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#43840',
},
titleContainer: {
flex: 1,
padding: 16,
justifyContent: 'center',
backgroundColor: '#559974',
},
title: {
color: 'white',
fontWeight: 'bold',
fontSize: 15,
},
});
To use flex property on child tag your parent tag needs to have a display: "flex" property on it.
container: {
display: 'flex',
flexDirection: 'column',
flex: 1,
backgroundColor: '#43840',
},
I am still new to react-native and I have some troubles regarding the styling props of react-native.
I created a screen in my app and all my relevant code is this:
import React, {useState, useEffect} from 'react';
import {View, Text, StyleSheet, ActivityIndicator, Alert, ImageBackground} from 'react-native';
import { TextInput } from 'react-native-gesture-handler';
import {useDispatch, useSelector} from 'react-redux';
const NewLetterScreen = props =>{
return(
<View style={{flex:1}}>
<ImageBackground source={require('../components/pictures/welcome.png')} style={{width:"100%", height:"100%", alignItems: 'center', justifyContent: 'center'}}>
<ImageBackground source={require('../components/pictures/letters/paper1.jpg')} style={styles.paper}>
</ImageBackground>
</ImageBackground>
</View>
)
};
const styles = StyleSheet.create({
paper:{
width: "90%",
height: "90%"
}
});
export default NewLetterScreen;
The problem I face now is, that the "paper" I want to display is not centered, even tho I stricly declare this in the wrapping ImageBackground with justifyContent and alignItems. It is displaced to far up and to far on the left side and looks like this:
Also, if I try to use padding to get this stuff centered somehow, it doesnt work. I want to do padding from left and right, so horizontaly, but if I apply "paddingHorizontal: 50" to my styles.paper, the result is the following:
As you see, the "paddingHorizontal:50" works like a paddingLeft and that is definitely not what I intend.
I would be happy about any help regarding my styling props. Thanks in advance!
Why not add a margin of 10%? I always have problems with paddings. Try to avoid them.
Edit: Maybe it would help to just add a margin, instead of changing the width to 90%?
import React from "react";
import { ImageBackground, StyleSheet, Text, View } from "react-native";
const image = { uri: "https://reactjs.org/logo-og.png" };
const App = () => (
<View style={styles.container}>
<ImageBackground source={image} style={styles.image}>
<Text style={styles.text}>Inside</Text>
</ImageBackground>
</View>
);
const styles = StyleSheet.create({
container: {
flex: 1,
flexDirection: "column",
justifyContent: "center"
},
image: {
flex: 1,
resizeMode: "cover",
justifyContent: "center",
margin: "10%"
},
text: {
color: "white",
fontSize: 42,
fontWeight: "bold",
textAlign: "center",
backgroundColor: "#000000a0"
}
});
export default App;
You can copy&paste this example on https://reactnative.dev/docs/imagebackground
You just need to add a wrapper for the inside image. You don't need margins or paddings.
const image1 = { uri: "https://images.unsplash.com/photo-1597768130867-4c06bf86a2f3?ixid=MXwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHw%3D&ixlib=rb-1.2.1&auto=format&fit=crop&w=1950&q=80" };
const image2 = { uri: "https://images.unsplash.com/photo-1611085857146-7b13f8b0a74f?ixid=MXwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHw%3D&ixlib=rb-1.2.1&auto=format&fit=crop&w=641&q=80" };
const App = () => (
<View style={{ flex: 1 }}>
<ImageBackground source={image1} style={styles.background}>
<View style={styles.wrapper}>
<ImageBackground source={image2}
resizeMode="cover"
style={styles.paper}>
</ImageBackground>
</View>
</ImageBackground>
</View>
);
const styles = StyleSheet.create({
background: {
width: "100%",
height: "100%",
alignItems: 'center',
justifyContent: 'center'
},
wrapper: {
width: "90%",
height: "90%",
alignItems: 'center',
justifyContent: 'center',
},
paper: {
width: "100%",
height: "100%"
}
});
I'm having trouble trying to display a list of Views using flex with 100% height, the issue comes when it renders the list from Flat list, I might do something wrong with flex.
This is what I want: A Flat list with same height when scrolls I will go to another component
And this is What I am having a smashed List of all the rendered views
The flatList is just this :
<FlatList
pagingEnabled={true}
data={DATA}
renderItem={renderItem}
keyExtractor={(item) => item.id}
/>
And the container from the Views I am rendering looks like this (css)
container: {
alignItems: 'center',
// TODO: check how why the screen is forguetting the tab, thats why I put the height like that
width: '100%',
height: '100%',
justifyContent: 'space-around',
flex: 1,
},
Use onLayout to get the height of the parent container and use that to set the height of FlatList items:
Example Output:
Full source code:
//import { List, ListItem } from 'react-native-elements';
import React, { useState } from 'react';
import {
Text,
View,
FlatList,
StyleSheet,
SafeAreaView,
StatusBar,
} from 'react-native';
const attendants = [
{
courseName: 'comp',
lecturer: 'Akanbi T.B',
students: 'Tunde Ajagba',
date: '10/11/2020',
no: 1,
},
{
courseName: 'comp',
lecturer: 'Akanbi T.B',
students: 'Tunde Ajagba',
date: '09/11/2020',
no: 2,
},
{
courseName: 'comp',
lecturer: 'Akanbi T.B',
students: 'Tunde Ajagba',
date: '10/11/2020',
no: 3,
},
];
const App = () => {
const [data, setData] = useState(attendants);
const [layoutHeight, setHeight] = useState(100);
return (
<View style={styles.container}>
<View style={{ flex: 5 }}>
<FlatList
onLayout={(e) => {
setHeight(e.nativeEvent.layout.height);
console.log(e.nativeEvent.layout.height);
}}
style={{ flexGrow: 1, backgroundColor: 'pink', height: layoutHeight }}
data={data}
keyExtractor={(item) => item.no}
renderItem={({ item }) => (
<View
style={{
height: layoutHeight
}}>
<ListItem
customStyle={{ backgroundColor: 'black' }}
title={`${item.lecturer} ${item.courseName}`}
subtitle={item.students}
/>
</View>
)}
/>
</View>
<View
style={{
flex: 1,
backgroundColor: 'lightgreen',
justifyContent: 'center',
alignItems: 'center',
}}>
<Text style={[styles.subtitle, { fontSize: 20 }]}>Bottom Bar</Text>
</View>
</View>
);
};
const ListItem = ({ title, subtitle, customStyle }) => {
return (
<View style={styles.listContainer}>
<Text style={styles.title}>{title}</Text>
<Text style={styles.subtitle}>{subtitle}</Text>
</View>
);
};
const styles = StyleSheet.create({
container: {
marginTop: 30,
flex: 1,
},
listContainer: {
flex: 1,
backgroundColor: 'teal',
margin: 5,
paddingHorizontal: 5,
borderRadius: 4,
},
subtitle: { fontSize: 12, color: 'rgba(0,0,10,0.5)' },
title: {
fontSize: 14,
color: 'white',
fontWeight: 'bold',
textAlign: 'cetere',
},
});
export default App;
You can find the working app example here: Expo Snack
Flatlist is scrollview with many item inside and ScrollView content will calculator height of children render on it. So any item render on it need set height. height 100% will get height of parent and set for itself so you can not using height of scrollview content (infinity) and set for item inside.
I have a React Native View that I would like to have extend up to but not exceed a given width. Inside this View, I have a Text element that I would like to fill out the full width of its parent. It looks like this:
However, if I set the parent View to center align with alignSelf: 'center' the view will shrink to fit the text inside the Text view, like so:
Why does changing the alignment of a View cause it to change size, and how can I prevent this?
Expected Output:
Complete code to replicate this scenario:
import * as React from 'react';
import { Text, View, StyleSheet } from 'react-native';
export default function App() {
return (
<View style={styles.container}>
<View style={styles.box}>
<Text style={styles.paragraph}>Text</Text>
</View>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
backgroundColor: '#ecf0f1',
padding: 8,
},
box: {
backgroundColor: 'red',
height: 50,
maxWidth:200,
alignSelf: 'center' // <---REMOVE THIS LINE TO FILL VIEW
},
paragraph: {
textAlign: 'left',
backgroundColor: 'green',
},
});
Why adding width will not work
While setting a fixed width value would enforce the maximum size, it would prevent this element from shrinking down below that value. For this reason, specifying width is not a solution. Here is an example situation where the size of the view would extend past the display.
With width:
Expected:
import * as React from 'react';
import { Text, View, StyleSheet } from 'react-native';
export default function App() {
return (
<View style={styles.container}>
<View style={styles.box}>
<Text style={styles.paragraph}>Text</Text>
</View>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignContent:'center',//ADD THIS LINE
backgroundColor: '#ecf0f1',
padding: 8,
},
box: {
backgroundColor: 'red',
height: 50,
maxWidth:200,
},
paragraph: {
textAlign: 'left',
backgroundColor: 'green',
},
});
expo