I have a simple View which has two children, another View and a ScrollView. The ScrollView should be 5x higher than the View on the same level, using flexbox.
<View style={{ flex: 1}}>
<View style={{flex: 1, backgroundColor: 'powderblue'}}>
<Text>Add new stuff</Text>
<Button title="Browse Gallery" onPress={ openGallery } />
</View>
<ScrollView style={{flex: 5, backgroundColor: 'skyblue'}}>
<Text style={{ fontSize: 100}}>Scroll me plz</Text>
<Text style={{ fontSize: 100}}>Scroll me plz</Text>
</ScrollView>
</View>
So I simply added flex:1 and flex:5 to the children Views, but the in the rendered view both of them fit exactly to half of the screen. It looks as if the two flex attributes are ignored...
Btw, using a second View instead of the ScrollView works just fine!
Any ideas how to achieve the 1:5 ratio with a ScrollView?
ScrollView is a component which doesn't inherit the use of flex. What you want to do is wrap the ScrollView in a View which will create the flex ratio you desire.
<View style={{flex: 1}}>
<View style={{flex: 1, backgroundColor: 'powderblue'}}>
<Text>Add new stuff</Text>
<Button title="Browse Gallery" onPress={ openGallery } />
</View>
<View style={{flex: 5}}>
<ScrollView style={{backgroundColor: 'skyblue'}}>
<Text style={{ fontSize: 100}}>Scroll me plz</Text>
<Text style={{ fontSize: 100}}>Scroll me plz</Text>
</ScrollView>
</View>
</View>
To achieve 1:5 screen ratio, having child component View and ScrollView with respect to parent View, you can code it in following manner:
<View style={{ flex: 1}}>
<View style={{flex: 1/5, backgroundColor: 'powderblue'}}>
<Text>Add new stuff</Text>
<Button title="Browse Gallery" onPress={ openGallery } />
</View>
<ScrollView style={{flex: 4/5, backgroundColor: 'skyblue'}}>
<Text style={{ fontSize: 100}}>Scroll me plz</Text>
<Text style={{ fontSize: 100}}>Scroll me plz</Text>
<Text style={{ fontSize: 100}}>Scroll me plz</Text>
</ScrollView>
</View>
Related
I'm new to react native, and I'm trying to make a social media app. I want to make it where you can scroll vertically to view certain posts, and then scroll horizontally to see other posts by the same user. I downloaded a UI framework, and it scrolls vertically, but how would I make the posts scroll horizontally?
Home.js
import React from 'react';
import {View,Text,Image,ImageBackground,TouchableOpacity} from 'react-native';
import {ScrollView,TextInput} from 'react-native-gesture-handler';
import Icon from '#expo/vector-icons/Entypo';
import Posts from '../screens/Posts'
export default class Home extends React.Component{
state={
popularSelected:true
}
onTabPressed=()=>{
this.setState({popularSelected:!this.state.popularSelected})
}
render(){
return(
<ScrollView
showsVerticalScrollIndicator={false}
style={{
height:"100%",
backgroundColor:"#b5f8d9"
}}
>
<View style={{
height:260,
width:"100%",
paddingHorizontal:35
}}>
<View style={{
flexDirection:"row",
width:"100%",
paddingTop:40,
alignItems:"center"
}}>
<View style={{
width:"50%"
}}>
<Image source={require('../images/Untitled.png')}
style={{width:20,height:20}}/>
</View>
<View style={{
width:"50%",
alignItems:"flex-end",
}}>
<Icon name = "dots-two-vertical"
size={22}
color="#d2d2d2"
style={{
marginRight:-7,
marginTop:7
}}/>
</View>
</View>
<View>
<Image source={require('../images/logoVizzey.jpg')} style={{width:200, height:80}}/>
</View>
{/* <Text style={{
fontFamily:"Bold",
fontSize:25,
color:"#FFF",
paddingVertical:25
}}>Vizzey</Text> */}
<View style={{
flexDirection:"row",
borderColor:"#9ca1a2",
borderRadius:20,
borderWidth:0.2,
paddingVertical:5,
alignItems:"center"
}}>
<TextInput
placeholder="search inispiration ..."
style={{
paddingHorizontal:20,
fontFamily:"Medium",
fontSize:11,
width:"90%",
color:"#9ca1a2"
}}
/>
<Icon name="magnifying-glass"
size={15}
color="#9ca1a2"/>
</View>
</View>
<View style={{
backgroundColor:"#FFF",
borderTopLeftRadius:40,
borderTopRightRadius:40,
height:1000,
paddingHorizontal:35
}}>
<View style={{
flexDirection:"row",
paddingTop:20
}}>
<TouchableOpacity
onPress={this.onTabPressed}
style={{
borderBottomColor:this.state.popularSelected ? "#044244":"#FFF",
borderBottomWidth:4,
paddingVertical:6
}}
>
<Text style={{
fontFamily:"Bold",
color:this.state.popularSelected ? "#044244":"#9ca1a2"
}}>MOST POPULAR</Text>
</TouchableOpacity>
<TouchableOpacity
onPress={this.onTabPressed}
style={{
borderBottomColor:this.state.popularSelected ? "#FFF":"#044244",
borderBottomWidth:4,
paddingVertical:6,
marginLeft:30
}}
>
<Text style={{
fontFamily:"Bold",
color:this.state.popularSelected ? "#9ca1a2":"#044244"
}}>RECENT</Text>
</TouchableOpacity>
</View>
<View style={{
flexDirection:"row"
}}>
<Posts
onPress={()=>this.props.navigation.navigate('Detail')}
name="Max Bator"
profile={require('../images/p1.jpg')}
photo={require('../images/5.jpg')}
/>
<View style={{
height:160,
backgroundColor:"#3c636c",
width:20,
marginLeft:20,
marginTop:120,
borderTopLeftRadius:20,
borderBottomLeftRadius:20
}}>
</View>
</View>
<View style={{
flexDirection:"row"
}}>
<View style={{
height:160,
backgroundColor:"#3c636c",
width:20,
marginLeft:-40,
marginRight:20,
marginTop:120,
borderTopRightRadius:20,
borderBottomRightRadius:20
}}>
</View>
<Posts
onPress={()=>this.props.navigation.navigate('Detail')}
name="Erka Berka"
profile={require('../images/p2.jpg')}
photo={require('../images/6.jpg')}
/>
</View>
<View style={{
flexDirection:"row"
}}>
<Posts
onPress={()=>this.props.navigation.navigate('Detail')}
name="Max Bator"
profile={require('../images/p1.jpg')}
photo={require('../images/3.jpg')}
/>
<View style={{
height:160,
backgroundColor:"#3c636c",
width:20,
marginLeft:20,
marginTop:120,
borderTopLeftRadius:20,
borderBottomLeftRadius:20
}}>
</View>
</View>
</View>
</ScrollView>
)
}
}
Posts.js
import React from 'react';
import {View,Text,Image,ImagBackground, ImageBackground} from 'react-native';
import Icon from "#expo/vector-icons/Entypo"
import {TouchableOpacity} from 'react-native-gesture-handler';
export default class Posts extends React.Component{
state={
liked:false
}
onLike=()=>{
this.setState({liked:!this.state.liked})
}
render(){
const {name,profile,photo,onPress} = this.props
return(
<View>
<View style={{
flexDirection:"row",
paddingTop:25,
alignItems:"center"
}}>
<View style={{width:"20%"}}>
<Image
source={profile}
style={{
width:45,
height:45,
borderRadius:13
}}
/>
</View>
<View style={{
width:"60%"
}}>
<Text style={{
fontFamily:"Bold",
fontSize:14,
color:"#044244"
}}>{name}</Text>
<Text style={{
fontFamily:"Medium",
fontSize:12,
color:"#9ca1a2"
}}>
2 mins ago
</Text>
</View>
<View style={{
width:"20%",
alignItems:"flex-end"
}}>
<Icon
name="sound-mix"
color="#044244"
size={20}
/>
</View>
</View>
<View style={{
flexDirection:"row",
width:"100%",
paddingTop:20
}}>
<ImageBackground
source={photo}
style={{
width:"100%",
height:220,
}}
imageStyle={{
borderRadius:30
}}
>
<View style={{
height:"100%",
flexDirection:"row",
alignItems:'flex-end',
justifyContent:"flex-end"
}}>
<TouchableOpacity
onPress={onPress}
style={{
marginBottom:20,
borderRadius:5,
padding:5,
backgroundColor:"#e8e8e8"
}}
>
<Icon name="forward"
color="#044244"
size={20}/>
</TouchableOpacity>
<TouchableOpacity
onPress={this.onLike}
style={{
marginBottom:20,
borderRadius:5,
padding:5,
backgroundColor:"#e8e8e8",
marginLeft:10,
marginRight:20
}}
>
<Icon name= {this.state.liked === true ? "heart":"heart-outlined"}
color= {this.state.liked===true? "red":"#044244"}
size={20}/>
</TouchableOpacity>
</View>
</ImageBackground>
</View>
</View>
)
}
}
Here is a picture of the UI:
Add horizontal attribute to ScrollView or any Scroll component.
<ScrollView horizontal></ScrollView>
I see that you have added ImageBackground twice in your imports in post.js file
to make it scroll horizontally, use the property horizontal
<ScrollView
horizontal
>
//other code goes here
</ScrollView>
see docs
https://reactnative.dev/docs/scrollview
is it possible to change the color of the bottom bar?
I would like to color it white. Do you have any ideas?
Goal:
return (
<Fragment>
<SafeAreaView style={{ flex: 0, backgroundColor: "red" }} />
<SafeAreaView style={{ flex: 1, backgroundColor: "white" }}>
<View style={styles.app}>
<View style={styles.header}>
<Image
accessibilityLabel="React logo"
source={{ uri: logoUri }}
resizeMode="contain"
style={styles.logo}
/>
</View>
<Text style={styles.text}>
This is an example of an app built with{" "}
</Text>
<Text style={styles.text}>To get started, edit .</Text>
<Button onPress={() => {}} title="Example button" />
</View>
</SafeAreaView>
</Fragment>
Can You try this?
Receiving syntax error, SyntaxError: Unexpected token, expected ",". It is for the third to last line ");"
I am having trouble seeing where I need to insert the ",". I have tried in front of the ); and after. No luck. This is while I was adding the code for google sign in for ios. Would appreciate any assistance.
render() {
LayoutAnimation.easeInEaseOut();
const scrollEnabled = this.state.screenHeight > height;
return (this.state.logedin ?
<View style={styles.container}>
<StatusBar barStyle="light-content"></StatusBar>
<ScrollView
style={{ flex: 1 }}
contentContainerStyle={styles.scrollview}
scrollEnabled={scrollEnabled}
onContentSizeChange={this.onContentSizeChange}
>
<ImageBackground source={require("/Users/carloscraig/NoExcusasRN/screens/assets/grassbcg2.png")}
style={{ width: '100%', height: '100%' }}>
<Image source={require("/Users/carloscraig/NoExcusasRN/screens/assets/noexlogo.png")}
style={styles.logo}>
</Image>
<Text style={styles.greeting}>{'BIENVENIDO!'}</Text>
<View style={styles.errorMessage}>
{this.state.errorMessage && <Text style={styles.error}>{this.state.errorMessage}</Text>}
</View>
<View style={styles.form}>
<View>
<Text style={styles.inputTitle}>correo electrónico</Text>
<TextInput
style={styles.input}
autoCapitalize="none"
onChangeText={email => this.setState({ email })}
value={this.state.email}
></TextInput>
</View>
<View style={{ marginTop: 32 }}>
<Text style={styles.inputTitle}>contraseña</Text>
<TextInput
style={styles.input}
secureTextEntry
autoCapitalize="none"
onChangeText={password => this.setState({ password })}
value={this.state.password}
></TextInput>
</View>
</View>
<TouchableOpacity style={styles.button} onPress={this.handleLogin}>
<Text style={{ color: "#FFF", fontWeight: "500" }}>Iniciar Sesión</Text>
</TouchableOpacity>
<SafeAreaView style={{
flex: 1,
justifyContent: 'center'
}}>
<Image style={{
width: 300,
height:300,
justifyContent: 'center',
alignSelf: 'center'
}} source={{uri: this.state.photo}} />
<Text>{this.state.name}</Text>
<Text>{this.state.email}</Text>
</SafeAreaView>:
<SafeAreaView style={{
flex: 1,
justifyContent: 'center',
alignItems: 'center'
}}>
<GoogleSigninButton
style={{ width: 192, height: 48 }}
size={GoogleSigninButton.Size.Wide}
color={GoogleSigninButton.Color.Light}
onPress={this._signIn}
disabled={this.state.isSigninInProgress} />
</SafeAreaView>
<TouchableOpacity
style={{ alignSelf: "center", marginTop: 32 }}
onPress={() => this.props.navigation.navigate("Register")}
>
<Text style={{ color: "#414959", fontSize: 13 }}>
No tienes una Cuenta? <Text style={{ fontWeight: "500", color: "#E9446A" }}>Regístrate</Text>
</Text>
</TouchableOpacity>
</ImageBackground>
</ScrollView>
</View>
);
}
}
React conditional rendering
render() {
const isLoggedIn = this.state.isLoggedIn;
return (
<div>
{isLoggedIn
? <LogoutButton onClick={this.handleLogoutClick} />
: <LoginButton onClick={this.handleLoginClick} />
}
</div>
);
}
You need to add the other half (false case) to the ternary. In this case if you do not want to render anything you need to return null.
render() {
LayoutAnimation.easeInEaseOut();
const scrollEnabled = this.state.screenHeight > height;
return (this.state.logedin ?
<View style={styles.container}>
<StatusBar barStyle="light-content"></StatusBar>
<ScrollView
style={{ flex: 1 }}
contentContainerStyle={styles.scrollview}
scrollEnabled={scrollEnabled}
onContentSizeChange={this.onContentSizeChange}
>
<ImageBackground source={require("/Users/carloscraig/NoExcusasRN/screens/assets/grassbcg2.png")}
style={{ width: '100%', height: '100%' }}>
<Image source={require("/Users/carloscraig/NoExcusasRN/screens/assets/noexlogo.png")}
style={styles.logo}>
</Image>
<Text style={styles.greeting}>{'BIENVENIDO!'}</Text>
<View style={styles.errorMessage}>
{this.state.errorMessage && <Text style={styles.error}>{this.state.errorMessage}</Text>}
</View>
<View style={styles.form}>
<View>
<Text style={styles.inputTitle}>correo electrónico</Text>
<TextInput
style={styles.input}
autoCapitalize="none"
onChangeText={email => this.setState({ email })}
value={this.state.email}
></TextInput>
</View>
<View style={{ marginTop: 32 }}>
<Text style={styles.inputTitle}>contraseña</Text>
<TextInput
style={styles.input}
secureTextEntry
autoCapitalize="none"
onChangeText={password => this.setState({ password })}
value={this.state.password}
></TextInput>
</View>
</View>
<TouchableOpacity style={styles.button} onPress={this.handleLogin}>
<Text style={{ color: "#FFF", fontWeight: "500" }}>Iniciar Sesión</Text>
</TouchableOpacity>
<SafeAreaView style={{
flex: 1,
justifyContent: 'center'
}}>
<Image style={{
width: 300,
height: 300,
justifyContent: 'center',
alignSelf: 'center'
}} source={{ uri: this.state.photo }} />
<Text>{this.state.name}</Text>
<Text>{this.state.email}</Text>
</SafeAreaView>:
<SafeAreaView style={{
flex: 1,
justifyContent: 'center',
alignItems: 'center'
}}>
<GoogleSigninButton
style={{ width: 192, height: 48 }}
size={GoogleSigninButton.Size.Wide}
color={GoogleSigninButton.Color.Light}
onPress={this._signIn}
disabled={this.state.isSigninInProgress} />
</SafeAreaView>
<TouchableOpacity
style={{ alignSelf: "center", marginTop: 32 }}
onPress={() => this.props.navigation.navigate("Register")}
>
<Text style={{ color: "#414959", fontSize: 13 }}>
No tienes una Cuenta? <Text style={{ fontWeight: "500", color: "#E9446A" }}>Regístrate</Text>
</Text>
</TouchableOpacity>
</ImageBackground>
</ScrollView>
</View>
: null);
}
I would like to show on the homepage of my react native app , a view that in turn shows a text element and an icon, then below these 2 I would like to show the amazon logo. I tried but it only shows me the logo.
export default class Header extends Component {
render() {
return (
<View style={{ flex: 1, flexDirection: 'row' }}>
<Text style={styles.Title}>Acquista!</Text>
<Ionicons name="ios-contact" size={42} color='red' style={{ marginTop:
65, marginLeft: 210 }} />
</View> ,
<Logo></Logo>
);
}
}
class Logo extends Component {
render() {
return (
<View>
<Image
style={{ height: 200, width: 200, marginTop: 150 }}
source={require('./assets/images/amazon.jpg')}
/>
</View>
);
}
}
Wrap everything into a View
return (
<View style={{ flex: 1 }}>
<View style={{ flex: 1, flexDirection: 'row' }}>
<Text style={styles.Title}>Acquista!</Text>
<Ionicons name="ios-contact" size={42} color='red' style={{ marginTop: 65, marginLeft: 210 }} />
</View>
<Logo />
</View>
)
Check this snippet:
import React, { Component } from 'react';
import { Text, View} from 'react-native';
export default class App extends Component {
render() {
return (
<View style={{margin: 80}}>
<View style={{ padding: 5, backgroundColor: 'honeydew', borderWidth: '1', borderColor: 'black'}}>
<View style={{margin:5, flexDirection: 'row'}}>
<View>
<Text style={{width:50}}>Test </Text>
</View>
<View style={{backgroundColor:'yellow'}}>
<Text>this text exceeds the bordered view on iphone, should just wrap and fill the view</Text>
</View>
</View>
</View>
</View>
);
}
}
The text with yellow background is rendered partially outside the view with the black border.
This can be tested here: https://snack.expo.io/HJRRjutuW
Why doesn't it render properly? And what should I change so it does?
Just remove flexDirection: 'row' from
<View style={{margin:5, flexDirection: 'row'}}>
also updated snack
https://snack.expo.io/rJ6N8tKdb
Or you can add flexWrap
<View style={{margin:5, flexDirection: 'row',flexWrap: 'wrap'}}>
output will be like
EDIT
import React, { Component } from 'react';
import { Text, View} from 'react-native';
export default class App extends Component {
render() {
return (
<View style={{margin: 80}}>
<View style={{ padding: 5, backgroundColor: 'honeydew', borderWidth: '1', borderColor: 'black'}}>
<View style={{margin:5, flexDirection: 'row', flexWrap: 'wrap', justifyContent: 'space-between'}}>
<View >
<Text style={{width:50}}>Test </Text>
</View>
<View style={{flex:1,backgroundColor:'yellow'}}>
<Text>this text exceeds the bordered view on iphone, should just wrap and fill the view</Text>
</View>
</View>
</View>
</View>
);
}
}
If I measure the screenwidth and subtract the rest from it, it looks like I want it to, but this is not an elegant solution:
https://snack.expo.io/r1xCX5td-
import React, { Component } from 'react';
import { Text, View, Dimensions} from 'react-native';
export default class App extends Component {
render() {
let stretchWidth = Dimensions.get('window').width - 240;
return (
<View style={{margin: 80}}>
<View style={{ padding: 5, backgroundColor: 'honeydew', borderWidth: '1', borderColor: 'black'}}>
<View style={{margin:5, flexDirection: 'row', flexWrap: 'wrap', justifyContent: 'space-between'}}>
<View style={{flexDirection: 'row'}}>
<Text style={{width:50}}>Test</Text>
</View>
<View style={{width:stretchWidth,backgroundColor:'yellow'}}>
<Text>this text exceeds the bordered view on iphone, should just wrap and fill the view</Text>
</View>
</View>
</View>
</View>
);
}
}