react native scrollView Height always stays static and does not change - react-native

I build react native app and I use with scrollView for header with list of text horizontal.
The issue is that the height of the scroll view takes half size of the screen. Even after declared it as a style, it still stays as it is.
screen with the scrollView
<View style={Style.container} >
{this.props.ExtendedNavigationStore.HeaderTitle ? <BackHeader header={this.props.ExtendedNavigationStore.HeaderTitle} onPressBack={this.goBack} /> : <Header openDrawer={this.openDrawer} />}
<ScrollView contentContainerStyle={{flexGrow:1}} style={Style.scrollableView} horizontal showsHorizontalScrollIndicator={false}>
{this.renderScrollableHeader()}
</ScrollView>
<Routes /> /* stack with dashboard screen */
</View>
</Drawer>
)
}
styles
import {StyleSheet} from 'react-native'
import {calcSize} from '../../utils'
const Styles = StyleSheet.create({
container : {
flex:1,
backgroundColor:"#e9e7e8"
},
scrollableView:{
height: calcSize(40),
backgroundColor: '#000',
},
textCategory:{
fontSize: calcSize(25),
color:'#fff'
},
scrollableButton:{
flex:1,
margin:calcSize(30)
}
})
export default Styles
As you can see the black size is the scroll View,
I want it to be small.
In routes stack into dashboard screen, the style:
const Style = StyleSheet.create({
container: {
backgroundColor: '#9BC53D',
flex: 1,
justifyContent: 'space-around',
alignItems: 'center'
},
text: {
fontSize: 35,
color: 'white',
margin: 10,
backgroundColor: 'transparent'
},
button: {
width: 100,
height: 75,
margin: 20,
borderWidth: 2,
borderColor: "#ecebeb",
justifyContent: "center",
alignItems: "center",
borderRadius: 40
}
})

There is an existing limitation with ScrollView where height cannot be provided directly.
Wrap the ScrollView in another View and give height to that View.
Like,
render() {
return (
<View style={styles.container}>
<View style={{height: 80}} >
<ScrollView
horizontal
style={{ backgroundColor: 'blue'}}
>
<Text style={{padding: 24}} >title1</Text>
<Text style={{padding: 24}} >title2</Text>
<Text style={{padding: 24}} >title3</Text>
<Text style={{padding: 24}} >title4</Text>
<Text style={{padding: 24}} >title5</Text>
</ScrollView>
</View>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
paddingTop: Constants.statusBarHeight,
backgroundColor: '#ecf0f1',
},
});
snack sample: https://snack.expo.io/HkVDBhJoz
EXTRAS: Unlike height providing width to a ScrollView will work correctly

Use flexGrow:0 inside ScrollView style
<ScrollView style={{ flexGrow:0 }}>

That worked for me:
<ScrollView contentContainerStyle={{ flexGrow: 1 }}>
<View style={{ flexGrow: 1 }}>
...
</View>
</ScrollView>

Considering the issue that you are using fixed height for the header, and flex for the Routes maybe, the orientation for different devices would not scale well and would look weird.
Therefore you may consider switching it to the flex
Here is the example by adding flexGrow to the styles of the ScrollView since it accepts view props
<View style={{ flex: 1 }}>
<ScrollView style={{ flexGrow: 0.05, backgroundColor: 'red', paddingTop: 50 }} horizontal>
<View style={{ width: 100 }}><Text>Label</Text></View>
<View style={{ width: 100 }}><Text>Label</Text></View>
<View style={{ width: 100 }}><Text>Label</Text></View>
<View style={{ width: 100 }}><Text>Label</Text></View>
<View style={{ width: 100 }}><Text>Label</Text></View>
</ScrollView>
<View style={{ flex: 0.95, backgroundColor: 'green' }} />
</View>
and here's the link to the snack expo

Use maxHeight inside scrollview style
<ScrollView style={{ maxHeight: 40 }}>•••</ScrollView>

Setting minHeight: int, maxHeight: int to ScrollView should work where int is height in pixels.
example below
<ScrollView style={{ minHeight: 280, maxHeight: 260}}>

Related

Flex is not splitting components equally in react native

I'm trying to make a layout like this:
In order to do so, I've made two components named HalfWidthFullHeightCard and HalfWithHalfHeightCard.
I've created the HalfWidthFullHeightCell component as?
<TouchableOpacity onPress={pressEvent}>
<ImageBackground
source={sourcePath}
imageStyle={{ borderRadius: 8, resizeMode: 'cover', width: '100%' }}
style={styles.halfWidthCard}>
<Text style={styles.halfWidthCardHeading}>{heading}</Text>
<Text style={styles.halfWidthCardText}>{cardText}</Text>
</ImageBackground>
</TouchableOpacity>
...
halfWidthCard: {
backgroundColor: colors.brightYellow,
marginBottom: 10,
borderRadius: 8,
},
Based on the cardText the width of the card is calculated automatically and in the halfWidthCardText StyleSheet I've only had padding: 10
Next for HalfWithHalfHeightCard everything is the same except for the styling which is:
...
smallHalfWidthCard: {
backgroundColor: colors.brightYellow,
borderRadius: 8,
marginBottom: 10
},
smallHalfWidthCardHeading: {
padding: 10,
},
smallHalfWidthCardText: {
padding: 10,
},
Where I'm putting both of these components together I'm doing:
<ScrollView contentContainerStyle={{padding: 15}}>
<View style={{flexDirection: 'row',}}>
<HalfWidthFullHeightCell />
<View>
<HalfWithHalfHeightCell />
<HalfWithHalfHeightCell />
</View>
</View>
</ScrollView>
Now there are two problems:
Consider the gray area as the width of the device. The HalfWidthFullHeightCard takes 100% of the space and
The HalfWithHalfHeightCard are outside of the screen and also not of the same height as HalfWidthFullHeightCard.
So, how can I make these components flexible so that they adapt to the layout as screen size changes?
I would have made it like this
import * as React from 'react';
import { Text, View, StyleSheet, Dimensions } from 'react-native';
const ScreenWidth = Dimensions.get('window').width;
export default function App() {
return (
<View style={styles.container}>
<View style={styles.WholeBox}>
<View style={styles.Block}></View>
<View style={{ flex: 1 }}>
<View style={styles.Block}></View>
<View style={styles.Block}></View>
</View>
</View>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
backgroundColor: '#ecf0f1',
},
WholeBox: {
width: ScreenWidth,
height: 300,
flexDirection: 'row',
},
Block: {
flex: 1,
backgroundColor: '#DDA73A',
margin: 6,
borderRadius: 8,
},
});
Working Example Here

Not able to make corners of bottom sheet rounded in react-native-bottom-sheet

I am trying to make the corners of the bottom sheet provided by the react-native-bottom-sheet rounded by passing the style prop to it. But the rounded corners are being overlapped by something which I don't know. How do I make the the corners rounded?
Screenshot:
Code:
<BottomSheet
style={{
flex: 1,
borderWidth: 5,
borderColor: "red",
backgroundColor: "blue",
borderRadius: 50
}}
index={1}
ref={bottomSheetRef}
snapPoints={snapPoints}
onChange={handleSheetChange}
>
<View
style={{
backgroundColor: "lightgreen",
marginTop: 30,
flex: 1,
justifyContent: 'center',
alignItems: 'center'
}}
>
<View style={{ backgroundColor: "white" }}>
<Text>
I am back
</Text>
</View>
</View>
</BottomSheet>
This BottomSheet component is wrapped inside a View with flex: 1
Just added overflow: hidden to the BottomSheet's style prop and it worked.
I ran into the same problem but found another solution because I was using a Handler that was outside the BottomSheet so adding overflow: 'hidden' just hid my Handler.
Reading the code I realized that the style prop that is passed to BottomSheet is added to the code as containerStyle here, but the component in charge of defining the rounded corners is actually the BackgroundComponent which has the border radius in its styles.
So, in order to get a BottomSheet with a custom corner radius is better to add a separate backgroundComponent with all the modifications we want.
Like this:
function customBackground({ pointerEvents, style }) {
return (
<View
pointerEvents={pointerEvents}
style={[styles.bgContainer, style]}
/>
);
}
function renderSheet(){
return(
<BottomSheet
index={1}
ref={bottomSheetRef}
snapPoints={snapPoints}
onChange={handleSheetChange}
backgroundComponent={customBackground}
>
<View
style={{
backgroundColor: "lightgreen",
marginTop: 30,
flex: 1,
justifyContent: 'center',
alignItems: 'center'
}}
>
<View style={{ backgroundColor: "white" }}>
<Text>
I am back
</Text>
</View>
</View>
</BottomSheet>
;)
}
const styles = StyleSheet.create({
bgContainer: {
borderTopLeftRadius: 40,
borderTopRightRadius: 40,
backgroundColor: "blue"
},
})

Onpress of touchableopacity is not working with "absolute"

In my react native app i have view with centered text and edit icon i need to enable click functionality in this view. for that i used TouchableOpacity's onPress. and in my style i need absolute position . then my onPress is not working.
I have code like this:
<TouchableOpacity
style={styles.topBand}
onPress={this._editPatientInfo}
>
<View style={styles.topView}>
<View style={{ flex: 1 }}>
<Text style={styles.topTitle}>{topTitle}</Text>
</View>
<View style={{ alignSelf: "flex-end" }}></View>
<Icon
pencil
name="pencil"
type="font-awesome"
size={20}
onPress={ this._editPatientInfo}
/>
</View>
</TouchableOpacity>
styles:
topBand: {
width: "100%",
position: "absolute",
top: 0,
alignItems: "center",
padding: 5,
backgroundColor: Colors.topBandColor
}
topView: {
flexDirection: "row",
alignItems: "center"
}
When clicking the function is not getting triggered. If i remove position: "absolute", from the style(topBand) it will work but without that the position is not correct.
What is the problem? How should i resolve it?
You need to wrap your touchableOpacity with a view that has position absolute
then it may work
<View style={styles.wrapper}>
<TouchableOpacity
style={styles.topBand}
onPress={this._editPatientInfo}
>
<View style={styles.topView}>
<View style={{ flex: 1 }}>
<Text style={styles.topTitle}>{topTitle}</Text>
</View>
<View style={{ alignSelf: "flex-end" }}></View>
<Icon
pencil
name="pencil"
type="font-awesome"
size={20}
onPress={ this._editPatientInfo}
/>
</View>
</TouchableOpacity>
</View>
wrapper:{
width: "100%",
position: "absolute",
top: 0,
},
topBand: {
alignItems: "center",
padding: 5,
backgroundColor: Colors.topBandColor
}
topView: {
flexDirection: "row",
alignItems: "center"
}
Import TouchableOpacity from react-native-gesture-handler
import { TouchableOpacity } from 'react-native-gesture-handler'

react native text horizontal cutting, need full text in one line how to do that?

react-native version: "0.62.0", I tried this code
ui coming like this:
React Native
</View>
<View style={{flex:8}}>
<View style={{padding: 20, height: 200, backgroundColor: 'red'}}>
<Text style={fonts.bold}>View 1</Text>
</View>
<View style={{padding: 20, height: 200, backgroundColor: 'red'}}>
<Text style={fonts.bold}>View 1</Text>
</View>
<View style={{padding: 20, height: 200, backgroundColor: 'yellow'}}>
<Text>View 1</Text>
</View>
<View style={{padding: 20, height: 200, backgroundColor: 'green'}}>
<Text>View 1</Text>
</View>
</View>
</View>
How to do it?
give Text width greater than space occupied by characters with some padding
It looks like you did not provide the code for intended green view. The green view in your code is different. It is under yellow view.
Tip: For intended view try to remove height and width properties.
Created a sample according to your problem
import * as React from 'react';
import { Text, View, StyleSheet } from 'react-native';
export default function App() {
return (
<View style={styles.container}>
<View style={styles.wrapperStyle}>
<View style={styles.leftStyle}>
<Text style={styles.textStyle}>Trending</Text>
</View>
<View style={styles.rightStyle}>
<Text>View 1</Text>
</View>
</View>
<View style={styles.wrapperStyle}>
<View style={[styles.leftStyle, { backgroundColor: 'green' }]}>
<Text style={styles.textStyle}>Top_games</Text>
</View>
<View style={[styles.rightStyle, { backgroundColor: 'yellow' }]}>
<Text>View 2</Text>
</View>
</View>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
paddingTop: 20,
},
wrapperStyle: {
height: 200,
flexDirection: 'row'
},
leftStyle: {
flex: 2,
backgroundColor: 'gray',
alignItems: 'center',
justifyContent: 'center'
},
rightStyle: {
flex: 8,
backgroundColor: 'red',
alignItems: 'center',
justifyContent: 'center'
},
textStyle: {
transform: [{ rotate: '-90deg' }]
}
});
Somtetimes you have to change flex value according to your requirements.
Hope this helps you. Feel free for doubts.

React Native 100% width view in scrollView

I have a horizontal ScrollView
In this ScrollView I want to display multiple Full height and width Views.
I don't figure out how to set each View's width to 100%.
Actually it like they have a "auto" width (about 70%)
<SafeAreaView style={styles.container}>
<ScrollView
style={styles.info}
horizontal={true}
>
{this.state.list.map(item => (
<View style={styles.item}>...</View>
))}
</ScrollView>
</SafeAreaView>
And the styles
info: {
width: "100%",
height: "100%",
display: "flex"
},
item: { // props for the items in my views
display: "flex",
alignItems: "center",
justifyContent: "space-between",
height: "100%",
paddingTop: 30,
paddingBottom: 10
}
I tried to put width : "100%" but of course it didn't work as excepted
Thanks
You would have to calculate the width of the device or container.
import { Dimensions } from 'react-native';
const screenWidth = Dimensions.get('window').width;
If you don't want the dimensions of the device because you'll have to convert the width value of your View you could you the contentContainerStyle props of ScrollView :
<ScrollView
horizontal
showsHorizontalScrollIndicator={false}
contentContainerStyle={{
flexGrow: 1,
justifyContent: 'center',
width: '100%',
}}
>
{history.map((item, index) => (
<View
key={index}
style={{
height: '10%',
width: '60%',
backgroundColor: '#eee',
alignItems: 'center',
justifyContent: 'center'
}}>
<Text>
{ToDate(item.timestamp.seconds)[0]}
</Text>
</View>
))}
</ScrollView>
Hope this could help people out here !