Related
I'm trying to arrange my cards into something like this
But heres what I got
As you can see the TouchableOpacity (yellow color) takes more than half of the container width (orange color).
I've tried may things by adding width: "50%" and set alignItems with flex-start, flex-end, etc but it only make things worse.
Here's my card component code
const SmallMateriCard = (props) => {
return (
<NativeBaseProvider >
<Box maxW={"70%"} alignItems="flex-start" style={{backgroundColor:"blue"}}>
{/* <Pressable onPress={props.onPress}> */}
<Box
borderRadius={18}
overflow="hidden"
style={{
width: "100%",
backgroundColor: 'white',
shadowColor: '#000',
shadowOffset: {
width: 0,
height: 0,
},
shadowOpacity: 0.1,
shadowRadius: 3,
elevation: 4,
}}>
<Box>
<AspectRatio w="100%" ratio={6/5} >
{props.cardIcon && (
<Image
borderRadius={18}
source={{uri: props.cardIcon}}
alt="image"
/>
)}
</AspectRatio>
</Box>
<Stack px="6" py="6" >
<Text
style={[
font.family.extrabold,
{ fontSize: 15, color: color.primary },
]}>
{props.title}
</Text>
</Stack>
</Box>
{/* </Pressable> */}
</Box>
</NativeBaseProvider>
);
};
export default SmallMateriCard;
and here's my screen code
const UKKSekunderScreen = ({ navigation }) => {
return (
<SafeAreaView>
<View
style={[mixins.margin(16,16)]}>
<ScrollView >
<View style={[mixins.margin(16,16), layout.display.flex, layout.justify.between, { backgroundColor:"orange", flexDirection: 'row', flexWrap: 'wrap' }]}>
{UKK_SEKUNDER.map((item, key) => (
<TouchableOpacity key={key} style={{ backgroundColor:"yellow", }}>
<View
style={[layout.margin.vertical(10)]}
>
<SmallMateriCard {...item} />
</View>
</TouchableOpacity>
))}
</View>
</ScrollView>
</View>
</SafeAreaView>
);
};
export default UKKSekunderScreen;
Thanks in advance.
EDIT
Gaurav's solution works but there's a new problem when I integrated it with my expandable component. The cards are overlaps when the component is collapsed.
EDIT 2
Solved by adding overflow: 'hidden'.
Hey check this please https://snack.expo.dev/HUhqzIpYv
Hope it helps :)
I believe your desired output would be a flex row with wrap enabled such as:
<View style={{flex: 1, justifyContent: 'flex-start', alignItems: 'center'}}>
<View style={{
justifyContent: 'flex-start',
alignItems: 'center',
flexDirection:'row',
flexWrap: 'wrap'
}}>
<Box style={{width: '50%'}} {...} />
<Box style={{width: '50%'}} {...} />
<Box style={{width: '50%'}} {...} />
<Box style={{width: '50%'}} {...} />
....
</View>
</View>
You could add some padding and margin to the box to add some space in-between them.
Edit: Here's an example with plain text, just to notice the layout:
<View style={{flex: 1, alignItems: 'center', justifyContent: 'center'}}>
<View
style={{
justifyContent: 'flex-start',
alignItems: 'center',
flexDirection: 'row',
flexWrap: 'wrap',
}}>
<Text
style={{width: '40%', borderWidth: 2, padding: '10%', margin: '5%', textAlign: 'center'}}>
Text
</Text>
<Text
style={{width: '40%', borderWidth: 2, padding: '10%', margin: '5%', textAlign: 'center'}}>
Text
</Text>
<Text
style={{width: '40%', borderWidth: 2, padding: '10%', margin: '5%', textAlign: 'center'}}>
Text
</Text>
<Text
style={{width: '40%', borderWidth: 2, padding: '10%', margin: '5%', textAlign: 'center'}}>
Text
</Text>
<Text
style={{width: '40%', borderWidth: 2, padding: '10%', margin: '5%', textAlign: 'center'}}>
Text
</Text>
<Text
style={{width: '40%', borderWidth: 2, padding: '10%', margin: '5%', textAlign: 'center'}}>
Text
</Text>
<Text
style={{width: '40%', borderWidth: 2, padding: '10%', margin: '5%', textAlign: 'center'}}>
Text
</Text>
</View>
</View>
Today i tried to use following property - alignItems: 'baseline'
Whole code:
<View
style={{
flexDirection: "row",
justifyContent: "flex-start",
alignItems: "baseline",
top: "6%",
left: 12,
flex: 1,
}}
>
<Text style={{ color: "#c1c3c9", fontSize: 24 }}>question</Text>
<Text style={{ color: "#c1c3c9", fontSize: 26 }}>2</Text>
<Text style={{ color: "#51546e", fontSize: 24 }}>/16</Text>
</View>
and image from emulator
I want to put this on whole line.
Where is the problem?
I have a screen called Tools, which allows me to redirect my user to multiple child screens.
I want to align the text in the middle of the image. I got to do this:
But I have the impression that it is not perfectly aligned in the center, an offset is created, I do not know if you can see it.
Could you give me your help on this point, how can I improve this?
The code :
export default function Tools({navigation}) {
return (
<ScrollView>
<View style={styles.screen}>
<View style={styles.row}>
<Text style={{marginHorizontal: 25, fontSize: 16}}>{i18n.t("tools.action.account")}</Text>
<TouchableOpacity
onPress={() => navigation.navigate('Account')}
style={styles.roundButton}>
<Image source={require("../../assets/images/accounting.png")} style={styles.img}/>
</TouchableOpacity>
</View>
<View style={styles.row}>
<TouchableOpacity
onPress={() => navigation.navigate('Scan')}
style={styles.roundButton}>
<Image source={require("../../assets/images/barcode.png")} style={styles.img}/>
</TouchableOpacity>
<Text style={{marginHorizontal: 25, fontSize: 16}}>{i18n.t("tools.action.scanProducts")}</Text>
</View>
<View style={styles.row}>
<Text style={{marginHorizontal: 25, fontSize: 16}}>{i18n.t("tools.action.ticket")}</Text>
<TouchableOpacity
onPress={() => navigation.navigate('Tickets')}
style={styles.roundButton}>
<Image source={require("../../assets/images/ticket.png")} style={styles.img}/>
</TouchableOpacity>
</View>
<View style={styles.row}>
<TouchableOpacity
onPress={() => navigation.navigate('Checkout')}
style={styles.roundButton}>
<Image source={require("../../assets/images/cash-register.png")}
style={styles.img}/>
</TouchableOpacity>
<Text style={{marginHorizontal: 25, fontSize: 16}}>{i18n.t("tools.action.cash")}</Text>
</View>
<View style={styles.row}>
<Text style={{marginHorizontal: 25, fontSize: 16}}>{i18n.t("tools.action.products")}</Text>
<TouchableOpacity
onPress={() => navigation.navigate('Products')}
style={styles.roundButton}>
<Image source={require("../../assets/images/products.png")} style={styles.img}/>
</TouchableOpacity>
</View>
</View>
</ScrollView>
);
}
The style :
screen: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
},
row: {
flexDirection: 'row',
alignItems: 'center',
justifyContent:'center',
width : '100%',
},
roundButton: {
marginTop: 20,
width: 100,
height: 100,
justifyContent: 'center',
alignItems: 'center',
padding: 10,
borderRadius: 100,
backgroundColor: 'orange',
},
img: {
width: 50,
height: 50,
},
Remove marginTop from roundButton:
roundButton: {
width: 100,
height: 100,
justifyContent: 'center',
alignItems: 'center',
padding: 10,
borderRadius: 100,
backgroundColor: 'orange',
},
Working Example: Expo Snack
I added pink background just to highlight the row and show that text is centered, remove it later :)
Full Source Code:
export default function Tools({ navigation }) {
return (
<ScrollView>
<View style={styles.screen}>
<View style={styles.row}>
<Text style={{ marginHorizontal: 25, fontSize: 16 }}>
{('tools.action.account')}
</Text>
<TouchableOpacity
onPress={() => navigation.navigate('Account')}
style={styles.roundButton}>
<Image
source={{uri: "https://i.stack.imgur.com/t8vJf.jpg?s=328&g=1"}}
style={styles.img}
/>
</TouchableOpacity>
</View>
<View style={styles.row}>
<TouchableOpacity
onPress={() => navigation.navigate('Scan')}
style={styles.roundButton}>
<Image
source={{uri: "https://i.stack.imgur.com/t8vJf.jpg?s=328&g=1"}}
style={styles.img}
/>
</TouchableOpacity>
<Text style={{ marginHorizontal: 25, fontSize: 16 }}>
{('tools.action.scanProducts')}
</Text>
</View>
<View style={styles.row}>
<Text style={{ marginHorizontal: 25, fontSize: 16 }}>
{('tools.action.ticket')}
</Text>
<TouchableOpacity
style={styles.roundButton}>
<Image
source={{uri: "https://i.stack.imgur.com/t8vJf.jpg?s=328&g=1"}}
style={styles.img}
/>
</TouchableOpacity>
</View>
<View style={styles.row}>
<TouchableOpacity
style={styles.roundButton}>
<Image
source={{uri: "https://i.stack.imgur.com/t8vJf.jpg?s=328&g=1"}}
style={styles.img}
/>
</TouchableOpacity>
<Text style={{ marginHorizontal: 25, fontSize: 16 }}>
{('tools.action.cash')}
</Text>
</View>
<View style={styles.row}>
<Text style={{ marginHorizontal: 25, fontSize: 16 }}>
{('tools.action.products')}
</Text>
<TouchableOpacity
style={styles.roundButton}>
<Image
source={{uri: "https://i.stack.imgur.com/t8vJf.jpg?s=328&g=1"}}
style={styles.img}
/>
</TouchableOpacity>
</View>
</View>
</ScrollView>
);
}
const styles = StyleSheet.create({
screen: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
},
row: {
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'center',
width: '100%',
backgroundColor: "pink",
margin: 5
},
roundButton: {
width: 100,
height: 100,
justifyContent: 'center',
alignItems: 'center',
padding: 10,
borderRadius: 100,
backgroundColor: 'orange',
},
img: {
width: 50,
height: 50,
},
});
I animate my view up 120 pixels when the keyboard opens for a Modal I have. When the keyboard closes, the view returns 120 pixels down. The problem is, the area that goes off screen at the top, when it gets animated back, the view is slightly smaller, and it gets slightly smaller each time, Here is the code - I will put a comment to show the view that is shrinking:
<Animated.View
style={{
paddingTop: 5,
paddingBottom: 10,
paddingLeft: 10,
paddingRight: 10,
marginTop: this.state.yPosition,
marginBottom: this.state.yPositionPositive,
flex: 1,
marginLeft: (Dimensions.get('window').width - 300) / 4,
backgroundColor: 'rgba(0,0,0,0.8)',
width: 300,
borderRadius: 4,
borderWidth: 0,
}}>
<View style={{ flexDirection: 'column', justifyContent: 'space-between', flex: 1 }}>
<View style={{height: 126, backgroundColor: 'blue', alignItems: 'stretch'}}>
<ScrollView contentContainerStyle={{flexGrow:1}} style={{flexDirection: 'column', backgroundColor: '#e6fffe'}}>
<View style={{height: 90, backgroundColor: 'red', flexDirection: 'row', justifyContent: 'center', alignItems: 'center', paddingTop: 5, paddingBottom: 5, borderBottomColor: '#6de3dc', borderBottomWidth: 0}}>
<View style={{justifyContent: 'center', alignItems: 'center', flex: 0.5}}>
<View style={{flexDirection: 'column', justifyContent: 'space-between'}}>
<Image
source={require('../assets/billythekid2.jpg')}
style={{height: 60, width: 60, marginTop: Platform.OS === 'ios' ? 10 : 10, borderColor: '#6de3dc', borderWidth: 2, borderRadius: 30}}
/>
<View style={{flexDirection: 'row', justifyContent: 'center', alignItems: 'center', marginTop: 5}}>
<Ionicons
name='ios-star'
color='#eec400'
size={14}
/>
<Ionicons
name='ios-star'
color='#eec400'
size={14}
/>
<Ionicons
name='ios-star'
color='#eec400'
size={14}
/>
<Ionicons
name='ios-star'
color='#eec400'
size={14}
/>
<Ionicons
name='ios-star'
color='#eec400'
size={14}
/>
</View>
</View>
</View>
<View style={{flexDirection: 'column', backgroundColor: '#e6fffe', marginTop: Platform.OS === 'ios' ? 10 : 10, flex: 0.5}}>
<View style={{flexDirection: 'row', flex: 0.5}}>
<View style={{flex: 0, alignSelf: 'center'}}>
<Text style={{fontSize: 16, fontWeight: '700'}}>
eamon.white
</Text>
</View>
</View>
</View>
</View>
<View style={{flex: 0, marginBottom: 5, backgroundColor: '#e6fffe'}}>
<Text
style={{
width: 280,
flex: 0,
backgroundColor: '#e6fffe',
paddingLeft: 5,
borderWidth: 0,
borderRadius: 4,
color: '#000',
fontSize: 14,
}}>
{this.state.messageFromSender}
</Text>
</View>
</ScrollView>
</View>
<View style={{flex: 1}} onLayout={(event) => {
this.setState({height: event.nativeEvent.layout.height});
}}>
<TouchableWithoutFeedback onPress={Keyboard.dismiss}>
<View style={{ flexDirection: 'column', flex: 1 }}>
<Text
style={{
flex: 0,
width: Dimensions.get('window').width,
color: 'white',
fontWeight: '700',
marginTop: 5,
marginBottom: 5
}}>
Date(s) Needed:
</Text>
{this.showCalendar()}
</View>
</TouchableWithoutFeedback>
<View style={{ flex: 0, marginBottom: 10, justifyContent: 'center', flexDirection: 'column', marginTop: 0 }}>
<TextInput
style={{
width: 280,
borderColor: 'gray',
borderWidth: 1,
backgroundColor: '#ffffff',
paddingLeft: 5,
borderRadius: 4,
height: this.state.height - 313
}}
onChangeText={text => this.setState({ message: text })}
value={this.state.message}
multiline={true}
numberOfLines={2}
onFocus={this.animateUp}
placeholder='Type a message...'
/>
</View>
</View>
<View style={{ flex: 0.1, borderRadius: 4, borderWidth: 0, marginBottom: 10 }}>
<TouchableOpacity
activeOpacity={1}
style={{
backgroundColor: this.state.rentButtonBackground,
flex: 1,
justifyContent: 'center',
alignItems: 'center',
width: 280,
borderRadius: 4,
borderWidth: 0,
}}
onPress={() => {
}}>
<Text
style={{
backgroundColor: this.state.rentButtonBackground,
textAlign: 'center',
color: 'white',
fontWeight: '900',
fontSize: 18,
borderRadius: 4,
borderWidth: 0,
}}>
RESPOND
</Text>
</TouchableOpacity>
</View>
<View style={{ flex: 0.1, borderRadius: 4, borderWidth: 0, marginBottom: 10 }}>
<TouchableOpacity
activeOpacity={1}
style={{
backgroundColor: this.state.rentButtonBackground,
flex: 1,
justifyContent: 'center',
alignItems: 'center',
width: 280,
borderRadius: 4,
borderWidth: 0,
}}
onPress={() => {
}}>
<Text
style={{
backgroundColor: this.state.rentButtonBackground,
textAlign: 'center',
color: 'white',
fontWeight: '900',
fontSize: 18,
borderRadius: 4,
borderWidth: 0,
}}>
ACCEPT
</Text>
</TouchableOpacity>
</View>
<View style={{ flex: 0.1, borderRadius: 4, borderWidth: 0 }}>
<TouchableOpacity
activeOpacity={1}
style={{
backgroundColor: this.state.rentButtonBackground,
flex: 1,
justifyContent: 'center',
alignItems: 'center',
width: 280,
borderRadius: 4,
borderWidth: 0,
}}
onPress={() => {
}}>
<Text
style={{
backgroundColor: this.state.rentButtonBackground,
textAlign: 'center',
color: 'white',
fontWeight: '900',
fontSize: 18,
borderRadius: 4,
borderWidth: 0,
}}>
DECLINE
</Text>
</TouchableOpacity>
</View>
</View>
</Animated.View>
Animations:
animateUp = () => {
Animated.parallel([
Animated.timing(this.state.yPosition, {
toValue: -120,
duration: 300,
}),
Animated.timing(this.state.yPositionPositive, {
toValue: 120,
duration: 300,
})
]).start();
}
Animated.parallel([
Animated.timing(this.state.yPosition, {
toValue: 0,
duration: 1,
}),
Animated.timing(this.state.yPositionPositive, {
toValue: 0,
duration: 1,
})
]).start()
It starts out like this:
Each time the keyboard opens and closes, and the animation happens, pushing the top of the modal off the screen, the ScrollView shrinks a little - until it ends up looking like this:
Any suggestions would be great.
If you need to animate a view when the keyboard opens, use KeyboardAvoidingView:
https://facebook.github.io/react-native/docs/keyboardavoidingview
I'm trying to imitate the image.
I'm having a problem with the button with the like in the middle I can not imitate it.
Since I read it seems that native react on android has a problem with overflow.
I thought you could use a:
marginTop: -25
but it does not seem to solve the problem.
Some advice?
Link expo: https://snack.expo.io/Hk1yUyzB7
Code:
import React, { Component } from 'react';
import { View, StyleSheet, Image, Text } from 'react-native';
//import ViewOverflow from 'react-native-view-overflow';
export default class App extends Component {
render() {
var account = (
<View>
<View
style={{
paddingTop: 20,
paddingLeft: 20,
flexDirection: 'row',
}}>
<Image
style={{ width: 50, height: 50, borderRadius: 25 }}
source={{
uri:
'http://www1.pictures.zimbio.com/bg/Number+Four+World+Premiere+h5-FoI0M8-gl.jpg',
}}
/>
<View
style={{
paddingLeft: 20,
}}>
<Text>Yulia James</Text>
<Text
style={{
color: '#ccc',
}}>
6 hrs ยท IIT London
</Text>
</View>
</View>
<Text
style={{
paddingTop: 20,
paddingLeft: 20,
paddingBottom: 20,
}}>
Making everyday worth it :)
</Text>
<View
style={{
paddingBottom: 20,
}}>
<Image
style={{
width: '100%',
height: 200,
}}
source={{
uri:
'http://www.wordzz.com/wp-content/uploads/2016/11/Night-Ratri.jpg',
}}
/>
</View>
</View>
);
var com = (
<View
style={{
backgroundColor: 'rgba(230,230,230,0.8)',
//height: 40,
alignItems: 'center',
//justifyContent: 'center',
padding: 5,
flex: 1,
}}>
<Text
style={{
color: '#ccc',
fontSize: 18,
}}>
Comment
</Text>
</View>
);
return (
<View
style={{
flex: 1,
backgroundColor: '#e7eff0',
}}>
<View
style={{
backgroundColor: 'rgba(255,255,255,0.8)',
marginTop: 50,
borderTopWidth: 1,
borderBottomWidth: 1,
borderColor: '#e7e7e7',
}}>
{account}
<View
style={{
backgroundColor: '#fff',
borderTopWidth: 1,
borderColor: '#ccc',
//alignItems: 'center',
//justifyContent: 'center',
}}>
<View style={styles.container2}>
{com}
<View
style={{
//backgroundColor: '#000',
borderRadius: 40,
height: 80,
width: 80,
alignItems: 'center',
justifyContent: 'center',
borderColor: '#ccc',
borderWidth: 1,
}}>
<Image
style={{
//resizeMode: 'cover',
height: 40,
width: 40,
}}
source={{
uri: 'http://i.imgur.com/k5jMsaH.gif',
}}
/>
</View>
{com}
</View>
</View>
</View>
</View>
);
}
}
const styles = StyleSheet.create({
container2: {
flexDirection: 'row',
},
});