React native horizontal scrollview does not scroll - css

Scroll view does not scroll, only shows first three items, the rest are lost.
<View style={styles.container}>
<ScrollView horizontal contentContainerStyle={{ flexGrow: 1 }}>
<View style={{ width: "33%" }}>
<TouchableOpacity style={styles.child}>
<Text>B1</Text>
</TouchableOpacity>
</View>
<View style={{ width: "33%" }}>
<TouchableOpacity style={styles.child}>
<Text>B2</Text>
</TouchableOpacity>
</View>
<View style={{ width: "33%" }}>
<TouchableOpacity style={styles.child}>
<Text>B3</Text>
</TouchableOpacity>
</View>
<View style={{ width: "33%" }}>
<TouchableOpacity style={styles.child}>
<Text>B4</Text>
</TouchableOpacity>
</View>
<View style={{ width: "33%" }}>
<TouchableOpacity style={styles.child}>
<Text>B5</Text>
</TouchableOpacity>
</View>
</ScrollView>
</View>
Here are the styles I am using
const styles = StyleSheet.create({
container: {
height: "10%",
width: "75%",
backgroundColor: "transparent",
borderRadius: 5,
borderTopWidth: 1,
borderBottomWidth: 1,
borderColor: "lightsteelblue",
display: "flex",
flexDirection: "row",
overflow: "hidden",
},
child: {
backgroundColor: "transparent",
flex: 1,
alignItems: "center",
justifyContent: "center",
},
});
I have already tried several of the solutions offered here on other posts and have not found a solution. Any contructive, good hearted criticism is welcome, thanks for your time.

This is how I can able to scroll, I've changed some css's, you can change as per your requirements
<View style={{flex: 1}}>
<ScrollView horizontal>
<View style={{flex: 1}}>
<TouchableOpacity style={styles.child}>
<Text>B1</Text>
</TouchableOpacity>
</View>
<View style={{flex: 1}}>
<TouchableOpacity style={styles.child}>
<Text>B2</Text>
</TouchableOpacity>
</View>
<View style={{flex: 1}}>
<TouchableOpacity style={styles.child}>
<Text>B3</Text>
</TouchableOpacity>
</View>
<View style={{flex: 1}}>
<TouchableOpacity style={styles.child}>
<Text>B4</Text>
</TouchableOpacity>
</View>
<View style={{flex: 1}}>
<TouchableOpacity style={styles.child}>
<Text>B5</Text>
</TouchableOpacity>
</View>
</ScrollView>
</View>
const styles = StyleSheet.create({
container: {
height: '50%',
backgroundColor: 'transparent',
borderRadius: 5,
borderTopWidth: 1,
borderBottomWidth: 1,
flexDirection: 'row',
},
child: {
backgroundColor: 'transparent',
width: 200,
height: 100,
alignItems: 'center',
justifyContent: 'center',
},
});

Here is a snack with your code that works.
https://snack.expo.io/#waheed25/horizontal-scroll-working-
Remove that flexGrow property and put width with respect to the device or a number and don't use percentage there as it was taking the width from the container.
or simply replace this code with your code.
<View style={styles.container}>
<ScrollView horizontal>
<View style={{ width: 100 }}>
<TouchableOpacity style={styles.child}>
<Text>B1</Text>
</TouchableOpacity>
</View>
<View style={{ width: 100 }}>
<TouchableOpacity style={styles.child}>
<Text>B2</Text>
</TouchableOpacity>
</View>
<View style={{ width: 100 }}>
<TouchableOpacity style={styles.child}>
<Text>B3</Text>
</TouchableOpacity>
</View>
<View style={{ width: 100 }}>
<TouchableOpacity style={styles.child}>
<Text>B4</Text>
</TouchableOpacity>
</View>
<View style={{ width: 100}}>
<TouchableOpacity style={styles.child}>
<Text>B5</Text>
</TouchableOpacity>
</View>
</ScrollView>
</View>

Related

How to Vertically and Horizontally align Modal in react native

I am trying to write a signup form and its loading screen modal.
For some reason the modal is not vertically and horizontally align
<View style={{flex: 1,flexDirection: 'column',alignItems: 'center'}}>
<View>
<Text>Something</Text>
<Text>Something</Text>
<Text>Something</Text>
<Text>Something</Text>
<Text>Something</Text>
<TouchableOpacity style={styles.button} onPress={() => alert('hello')}>
<Text style={styles.button_text}>CREATE YOUR NEW ACCOUNT</Text>
</TouchableOpacity>
</View>
<View style={{flex: 1, justifyContent: 'center', alignItems: 'center'}}>
<Modal
animationType="slide"
transparent={true}
visible={modalVisible}
onRequestClose={() => {
Alert.alert('Modal has been closed.');
setModalVisible(!modalVisible);
}}>
<View
style={{width: 300, height: 300, backgroundColor: 'red'}}></View>
</Modal>
</View>
</View>
Can someone help please, here is how current situation is,
I want the modal to horizontally and vertically align in the screen
Try this
<Modal
animationType="slide"
transparent={true}
visible={modalVisible}
onRequestClose={() => {
Alert.alert('Modal has been closed.');
setModalVisible(!modalVisible);
}}>
<View style={{flex: 1, justifyContent: 'center', alignItems: 'center'}}>
<View style={{width: 300, height: 300, backgroundColor: 'red'}}>
...other components you need
</View>
</View>
</Modal>

How do I style my json data on screen in form of table?

I have a screen where my data is displayed. I want to display in the form of table (The data at the bottom of screen)as shown below in screenshot.
Edited: top part code:
It's inside the movies as well
<View>
<Text key={item.symbol}>{item.symbol}<Text>
<Text key={item.open}>{item.open}<Text>
<Text key={item.close}>{item.close}<Text>
</View>
Right now my screen looks like:
I want to create an interface like below:
The data next to the close, high etc is some json data that I fetched from api.
My Code as of now :
let movie = (
<View style={styles.bottomdata}>
<Text style={styles.text} key={item.name}>
{item.name}
</Text>
<Text style={styles.text} key={item.open}>
OPEN {item.open}
</Text>
<Text style={styles.text} key={item.close}>
CLOSE{item.close}
</Text>
<Text style={styles.text} key={item.volumes}>
VOLUME{item.volumes}
</Text>
<Text style={styles.text} key={item.low}>
LOW {item.low}
</Text>
<Text style={styles.text} key={item.high}>
HIGH{item.high}
</Text>
</View>
)
return (
<TouchableWithoutFeedback onPress={Keyboard.dismiss}>
<View style={styles.container}>
<View>{movie}</View>
</View>
</TouchableWithoutFeedback>
);
}
const styles = StyleSheet.create({
text: {
color: "black",
backgroundColor: "white",
},
bottomdata:
{
marginTop:400,
backgroundColor:"black",
}
});
The movie is the data displayed on the screen. How do I design it like that? And, at the top it is just the symbol name (same as at the bottom) and close and high values. How can I design my screen like that? I am able to fetch the data but not sure how to design it like that.
You will have to use layout the contents using a views and test which would create something like a table. The below code shows how to position items in a row.
JSX
<View style={{ flex: 1 }}>
<View
style={{
flexDirection: 'row',
backgroundColor: 'black',
alignItems: 'center',
}}>
<Text style={{ flex: 0.5, color: 'white' }}>{item.symbol}</Text>
<Text style={{ flex: 0.5, color: 'white' }} key={item.open}>{item.open}</Text>
<Text
style={{
flex: 0.5,
color: 'white',
backgroundColor: 'red',
marginVertical: 5,
paddingHorizontal: 10,
borderRadius: 10,
}}
key={item.close}>
{item.close}
</Text>
</View>
<View style={styles.bottomdata}>
<Text style={[styles.text, { alignSelf: 'center' }]} key={item.name}>
{item.name}
</Text>
<View style={styles.row}>
<View style={styles.rowItem}>
<Text style={styles.text}>OPEN</Text>
<Text style={styles.text}>{item.open} </Text>
</View>
<View style={styles.rowItem}>
<Text style={styles.text}>CLOSE</Text>
<Text style={styles.text}>{item.close}</Text>
</View>
</View>
<View style={styles.row}>
<View style={styles.rowItem}>
<Text style={styles.text}>LOW</Text>
<Text style={styles.text}>{item.low} </Text>
</View>
<View style={styles.rowItem}>
<Text style={styles.text}>HIGH</Text>
<Text style={styles.text}>{item.high}</Text>
</View>
</View>
<View style={styles.rowItem}>
<Text style={styles.text}>VOLUME</Text>
<Text style={styles.text}>{item.volumes}</Text>
</View>
</View>
</View>
Styles
const styles = StyleSheet.create({
text: {
color: 'white',
},
bottomdata: {
marginTop: 'auto',
backgroundColor: 'black',
},
row: {
flexDirection: 'row',
width: '100%',
},
rowItem: {
width: '50%',
justifyContent: 'space-between',
flexDirection: 'row',
paddingHorizontal: 5,
},
});
You just need to make divs with some alignments and all and just get those data in the relavant field

How to change the color of a active button only in react native

there are four buttons how to change the color of the active one being press and change it back to normal if the other button is pressed
i tried this
state = { active: styles.btn };
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center', }}>
<View style={{ padding: 10 }}>
<TouchableOpacity onPress={() => {this.setState({ active: styles.btnActive })}}
style={this.state.active}>
<Text> town </Text>
</TouchableOpacity>
</View>
<View style={{ padding: 10 }}>
<TouchableOpacity onPress={() => {this.setState({ active: styles.btnActive })}}
style={this.state.active}>
<Text> hill </Text>
</TouchableOpacity>
</View>
<View style={{ padding: 10 }}>
<TouchableOpacity onPress={() => {this.setState({ active: styles.btnActive })}}
style={this.state.active}>
<Text> street </Text>
</TouchableOpacity>
</View>
<View style={{ padding: 10 }}>
<TouchableOpacity onPress={() => {this.setState({ active: styles.btnActive })}}
style={this.state.active}>
<Text> road </Text>
</TouchableOpacity>
</View>
</View>
const styles = StyleSheet.create({
btn: {
alignItems: 'center',
backgroundColor: '#DDDDDD',
borderColor: '#dc00ff',
borderRadius: 10,
borderWidth: 1,
padding: 10,
},
btnActive: {
alignItems: 'center',
backgroundColor: '#dc00ff',
borderColor: '#dc00ff',
borderRadius: 10,
borderWidth: 1,
padding: 10,
},
});
but instead all the buttons color are changing when one button is press
In React, whenever you do a this.setState() call the component get re-rendered. You buttons are looking to this.state.active for their styles, so whenever one button is pressed, the your this.state.active is getting updated to the btnActive styles you are passing it. I would recommend that you give each button an index so that you can distiguish between the buttons more easily.
Fair warning the code below is pretty static. If you need to make this more dynamic (say you want to generate buttons based on a list or something) you'd have to use map or a for loop, but the indexing idea would remain the same.
state = { active: null };
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center', }}>
<View style={{ padding: 10 }}>
<TouchableOpacity
onPress={() => {this.setState({ active: 0 })}}
style={this.state.active === 0 ? style.btnActive : style.btn }>
<Text> town </Text>
</TouchableOpacity>
</View>
<View style={{ padding: 10 }}>
<TouchableOpacity
onPress={() => {this.setState({ active: 1 })}}
style={this.state.active === 1 ? style.btnActive : style.btn }>
<Text> town </Text>
</TouchableOpacity>
</View>
<View style={{ padding: 10 }}>
<TouchableOpacity
onPress={() => {this.setState({ active: 2 })}}
style={this.state.active === 2 ? style.btnActive : style.btn }>
<Text> town </Text>
</TouchableOpacity>
</View>
<View style={{ padding: 10 }}>
<TouchableOpacity
onPress={() => {this.setState({ active: 3 })}}
style={this.state.active === 3 ? style.btnActive : style.btn }>
<Text> town </Text>
</TouchableOpacity>
</View>
</View>
The issue is that your code is using the state.active style for every button. What I'd do is store the active button index, or key, in state and then switch on that state to decide which style to use.
Life example: https://snack.expo.io/B1mPipDwr
state = {activeIndex: 0};
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center', }}>
<View style={{ padding: 10 }}>
<TouchableOpacity onPress={() => {this.setState({ activeIndex: 0 })}}
style={this.state.activeIndex === 0 ? styles.btnActive : styles.btn}>
<Text> town </Text>
</TouchableOpacity>
</View>
<View style={{ padding: 10 }}>
<TouchableOpacity onPress={() => {this.setState({ activeIndex: 1 })}}
style={this.state.activeIndex === 1 ? styles.btnActive : styles.btn}>
<Text> hill </Text>
</TouchableOpacity>
</View>
<View style={{ padding: 10 }}>
<TouchableOpacity onPress={() => {this.setState({ activeIndex: 2 })}}
style={this.state.activeIndex === 2 ? styles.btnActive : styles.btn}>
<Text> street </Text>
</TouchableOpacity>
</View>
<View style={{ padding: 10 }}>
<TouchableOpacity onPress={() => {this.setState({ activeIndex: 3 })}}
style={this.state.activeIndex === 3 ? styles.btnActive : styles.btn}>
<Text> road </Text>
</TouchableOpacity>
</View>
</View>
const styles = StyleSheet.create({
btn: {
alignItems: 'center',
backgroundColor: '#DDDDDD',
borderColor: '#dc00ff',
borderRadius: 10,
borderWidth: 1,
padding: 10,
},
btnActive: {
alignItems: 'center',
backgroundColor: '#dc00ff',
borderColor: '#dc00ff',
borderRadius: 10,
borderWidth: 1,
padding: 10,
}
});

react-native text doesn't align

My text component doesn't align when the text is more than 2 lines (see screenshot). I have tried playing around with alignment and ellipsizeMode but none of the settings change anything. Why is the 2nd line indented?
My code:
<View style={{ flex: 4, flexDirection: 'row', marginTop: 10}}>
<View style={{ flex: 1, alignItems: 'flex-end' }}>
<CircleIndicator style={{marginRight: 29}} />
<View
style={{
width: 4,
height: '100%',
backgroundColor: styles.colors.lipstick,
marginRight: 35,
}}
/>
</View>
<View style={{ flex: 2 }}>
<View style={{ flex: 1 }}>
<Text weight='bold' color='darkIndigo'> {activityType} </Text>
</View>
<View style={{ flex: 1 }}>
<Text color='blueyGrey' style={{opacity: 0.5}}> {activityDate}
</Text>
</View>
<View style={{ flex: 1, marginBottom: 30 }}>
<Text color='blueyGrey'> {activityDescription} </Text>
</View>
</View>
<View style={{ flex: 1 }} >
<Text weight='bold' color='lipstick'> {activityPoints} PTS </Text>
</View>
</View>
So I left this issue alone for a couple of days and revisited it. The reason for the misalignment was this:
<Text color='blueyGrey'> {activityDescription} </Text>
Changed it to:
<Text color='blueyGrey'>{activityDescription}</Text>
Such a rookie mistake :D

React-Native Align Issue

I just want the Icon to be on the left and the text to be on center.
I have this structure:
<View style={styles.mainContainer}>
<Error screen={screen}/>
<View style={styles.headerContainer}>
{back &&
<Icon
raised
name='arrow-back'
onPress={ onBackPress }
containerStyle={styles.back}/>
}
<Text style={styles.header}>{ title }</Text>
</View>
<View style={styles.contentContainer}>
{ children }
</View>
</View>
Kinda like this:
-> MainContainer
--> HeaderContainer
----> Back button
----> Title
mainContainer: {
flex: 1,
flexDirection: 'column',
alignItems: 'stretch',
justifyContent: 'flex-start'
},
headerContainer: {
flex: 1,
padding: 10,
flexDirection: 'row',
// ommited for clarity
},
back: {
alignSelf: 'flex-start'
},
header: {
fontSize: 24,
alignSelf: 'center'
},
But it doesnt work as it produces:
I also tried adding in HeaderContainer:
justifyContent: 'space-between',
and a blank <View />, but the result is not good:
As you can see, it's not centered really.
Edit Produces:
It's not really centered, because we put an imaginary thrid element. Can we do it with only two elemets? One in start and other on center?
Why is it not posible?
Try the following:
<View style={{ flex: 1, flexDirection: 'row', alignItems: 'center' }}>
<View style={{ flex: 1 }}>
{leftContent}
</View>
<View style={{ flex: 1, alignItems: 'center' }}>
{centerContent}
</View>
<View style={{ flex: 1, alignItems: 'flex-end' }}>
{rightContent}
</View>
</View>
Don't forget to set textAlign: 'center' if center component is <Text> or textAlign: 'right' if the right component is Text.
Put your Icon and text in separate Views and asign a flex to it something like this
<View style={styles.mainContainer}>
<Error screen={screen}/>
<View style={styles.headerContainer}>
<View style={{flex:.3,alignSelf:'flex-start}}>
{back &&
<Icon
raised
name='arrow-back'
onPress={ onBackPress }
containerStyle={styles.back}/>
}
</View>
<View style={{flex:.7,alignSelf:'flex-end',alignItems:'center'}}>
<Text style={styles.header}>{ title }</Text>
</View>
</View>
<View style={styles.contentContainer}>
{ children }
</View>
</View>
I think it shoud fix the problem

Resources