I would like to render an horizontal scroll view with two rows of items, where the items have dynamic sizes. I have already tried to set a height to the scroll view and apply to its containerStyle flex-wrap with flex direction column, as suggested here React Native horizontal FlatList with multiple rows.
However, the result is not as expected since two elements in a column take the same size.
<View style={{height: 80}}>
<ScrollView
horizontal={true}
containerStyle={{
flexDirection: "column",
flexWrap: "wrap",
alignItems: "flex-start"
}}
>
{data.map(d => renderElement(d))}
</ScrollView>
</View
renderElement = (d: string) => (
<View
style={{
justifyContent: "center",
alignItems: "center",
borderWidth: 1,
borderColor: "#898989",
backgroundColor: "white",
borderRadius: 12,
margin: 3,
height: 24
}}
>
<Text style={{marginHorizontal: 8, fontSize: 16, color:"#898989#"}}>
{d}
</Text>
</View>
)
current result:
Related
Im trying to change the opacity of a button when the user clicks it, (between 2 buttons the darker one would be his choice). For some reason whenever i click the button once the opacity doesn't change and it only changes after 2 clicks. Any ideas where im going wrong?
export default function lastName({ navigation }) {
let [opac, setOpacity] = useState(0.3);
return (
<View style={styles.container}>
<View
style={{
flex: 0.5,
justifyContent: "flex-end",
//backgroundColor: "red",
}}
>
<Text style={styles.textStyle}>
Select a button
</Text>
</View>
<View
style={{
flex: 1,
justifyContent: "flex-start",
}}
>
<TouchableOpacity
style={{
marginTop: 70,
alignItems: "center",
justifyContent: "center",
width: 180,
height: 40,
backgroundColor: "#004953",
opacity: opac,/// here
borderRadius: 100,
}}
onPress={() => {
setOpacity(1); // here
}}
>
<Text
style={{
color: "white",
textAlign: "center",
fontSize: 18,
}}
>
Button 1
</Text>
</TouchableOpacity>
Apparently, its a bug with touchable opacity, you have to wrap opacity in a view, refer to this link Dynamic Opacity not changing when component rerenders in react native
<View style={{ width: "100%",
minHeight: 100,
paddingHorizontal: 17}}>
<View
style={{
flexDirection: "row",
alignItems: "center",
justifyContent: "center",
flexWrap: "wrap",
boxSizing: "borderBox",
height: 56,
width: 312,
borderWidth: 1,
borderColor: "#FF6D00",
borderRadius: 2,
marginTop: 24,
paddingBottom: 10
}}
>
<SVGImg width={10} height={10} />
<Text h7 >
Feature is not there for this particular page.
<TouchableOpacity
onPress={() => this._onClickWhatisit()}
>
<Text h7>
What is it
</Text>
</TouchableOpacity>
</Text>
</View>
</View>
Output what i need should be in same line image then text and all in center and left aligned.That react native image should come before Feature text with some space.
Heres a full example of what I think you want (https://snack.expo.dev/#heytony01/great-waffles). Basically what I did was put two views next to each other as columns. Put the icon in one and the text in the other
I want to achieve the following:
I want to display a label next to a centered value.
As far as I can see that's not possible with flexbox, right?
How could I achieve that?
Additionally I'd like to have the base-aligned, but currently this option is not working on Android. Therefore I'm using hardcoded paddings for the smaller text boxes. Any other Idea for that?
Another suggestion, if you don't want to use empty Views, is to position Value to the center, and then have the unit positioned absolute (so it goes off the flex) and to the bottom so you ensure it's base-aligned to Value.
<View style={styles.container}>
<Text style={styles.value}>
Value
<Text style={styles.unit}>unit</Text>
</Text>
</View>
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
backgroundColor: 'lightgrey',
},
value: {
backgroundColor: '#eee',
textAlign: 'center',
fontSize: 20,
position: 'relative',
},
unit: {
fontSize: 12,
position: 'absolute',
bottom: 0,
},
});
You can use use 3 flex boxes placed horizontally to get a similar effect. Leave the left box blank.
(Ive added background colors for reference)
<View style={styles.container}>
<View
style={{
flexDirection: 'row',
}}>
<View style={{ flex: 1}} /> {/* blank view */}
<View
style={{
flex: 1,
justifyContent: 'flex-end',
alignItems: 'center',
}}>
<Text style={{ fontSize: 30 }}>Value</Text>
</View>
<View
style={{
flex: 1,
justifyContent: 'flex-end',
alignItems: 'fllex-start',
}}>
<Text style={{ fontSize: 12 }}>Unit</Text>
</View>
</View>
</View>
I have 5 items in FlatList.
I want my items render evenly in fullscreen(Top image to Bottom image).
If I change height or flex, It will shows 5 items in current backgroundImage space.
what should I change..?
<View
style={{
flex: 1,
flexDirection: 'column',
backgroundColor: 'black',
}}
>
<FlatList
style={{ flex: 1 }}
data={emotions}
renderItem={({ item }) => (
<ImageBackground
source={item.img}
style={{
width: '100%',
height: '100%',
justifyContent: 'center',
margin: 2,
alignContent: 'stretch',
}}
>
<Text
style={{
fontSize: 20,
textAlign: 'center',
color: 'white',
}}
onPress={() => this.handlePress(`${item.title}`)}
>
{item.title}
</Text>
</ImageBackground>
)}
keyExtractor={item => item.title}
numColumns={1}
></FlatList>
</View>
In render item can you try this
Please replace this
height: '100%'
with
flex:1
For the life of me, I can't center the headerTitle component. Ideas?
class GroupSelectionScreen extends React.Component{
static navigationOptions = ({navigation}) => {
return {
headerLeft: <View>
<Image source={logoImg} style={{width:72, height:33, marginLeft:5}}/>
</View>,
headerStyle: {
backgroundColor: theme.colors.darkBlue,
height: 75,
},
headerTitle: <View style={{
alignItems: "center",
flexDirection: 'row',
}}>
<View style={{backgroundColor: statusColor, width: 15, height: 15, borderRadius: 8}}></View>
<Text style={{color: 'white', fontSize: 25}}>{username}</Text>
</View>,
headerRight: <SetStatusButton onPress={navigation.getParam('toggleSetStatus')}/>,
};
};
Because you are using flexDirection:'row' you will probably want to add the property justifyContent:'center' to center the content of the view horizontally
This is due to the fact that justifyContent works on the primary axis and alignItems work on the secondary axis. Setting the flexDirection as row changes the primary axis to be row.
Adding flexDirection to a component's style determines the primary axis of its layout.
Adding justifyContent to a component's style determines the distribution of children along the primary axis.
You can see more in the docs
https://facebook.github.io/react-native/docs/flexbox
Here is a snack https://snack.expo.io/#andypandy/flexdirection
Each of the three views have flexDirection: 'row'
The first view has justifyContent: 'center' and the text is centred horizontally.
The second view has alignItems: 'center' and the text is centred vertically.
The third view has both justifyContent: 'center' and alignItems: 'center' and the text is centred horizontally and vertically
Here is an image of what it looks like
And here is the code
<View>
<View style={{flexDirection: 'row', justifyContent: 'center', backgroundColor: 'yellow', height: 100, width: 100, margin: 10}} >
<Text>Hello</Text>
</View>
<View style={{flexDirection: 'row', alignItems: 'center', backgroundColor: 'cyan', height: 100, width: 100, margin: 10}} >
<Text>Hello</Text>
</View>
<View style={{flexDirection: 'row', justifyContent: 'center', alignItems:'center', backgroundColor: 'forestgreen', height: 100, width: 100, margin: 10}} >
<Text>Hello</Text>
</View>
</View>
Update
In react-navigation there appears to be a difference between how headerTitle given by the question poster is handled in Android and iOS.
In iOS the headerTitle centres vertically and horizontally, however in Android it centres only vertically and is aligned left. Obviously this is not ideal.
There is a way to make it work in both iOS and Android, simply
Wrap the original header in a View with flex:1
Make sure the original header's View has a style with justifyContent: 'center' and alignItems: 'center'
Here is the code for the new headerTitle
<View style={{flex: 1}}>
<View style={{flexDirection: 'row', justifyContent: 'center', alignItems: 'center'}}>
<View style={{backgroundColor: 'green', width: 15, height: 15, borderRadius: 8}}/>
<Text>Spencer</Text>
</View>
</View>
Here is a snack showing it working https://snack.expo.io/#andypandy/navigation-header