ScrollView not scrolling in React Native - react-native

I just started learning how to use React Native and wanted to learn as I went while creating a simple project, I'm trying to create a ScrollView of card items but I can't seem to get it to scroll. I've been looking around stack overflow trying the solutions like flex:1 but I can't seem to get it to work.
Here is my code
<ScrollView contentContainerStyle={{flex:1}}>
<View style={{flexDirection:'row'}}>
<View style={{flex:0.5}}>
<View style={styles.card}><Text>Test</Text></View>
<View style={styles.card}><Text>Test2</Text></View>
<View style={styles.card}><Text>Test3</Text></View>
<View style={styles.card}><Text>Test4</Text></View>
<View style={styles.card}><Text>Test5</Text></View>
<View style={styles.card}><Text>Test6</Text></View>
<View style={styles.card}><Text>Test7</Text></View>
</View>
<View style={{flex:0.5}}>
<View style={styles.card}><Text>Testi</Text></View>
<View style={styles.card}><Text>Testii</Text></View>
<View style={styles.card}><Text>Testiii</Text></View>
<View style={styles.card}><Text>Testiv</Text></View>
<View style={styles.card}><Text>Testv</Text></View>
<View style={styles.card}><Text>Testvi</Text></View>
<View style={styles.card}><Text>Testvii</Text></View>
</View>
</View>
</ScrollView>
My CSS :
const styles = StyleSheet.create({
card:
{
height:'20%',
margin:10,
borderWidth:1,
borderColor:'#000',
borderStyle:'solid',
}
});

You have given flex 0.5 to both of the children views,
So here make sure that contents don't have fixed size in flex.
You can remove this 0.5 flex and give instead width:'50%' also remove flex:1 which is causing your scroll view to utilizing only viewable height.
<ScrollView>
<View style={{flexDirection:'row'}}>
<View style={{width:"50%"}}>
<View style={styles.card}><Text>Test</Text></View>
<View style={styles.card}><Text>Test2</Text></View>
<View style={styles.card}><Text>Test3</Text></View>
<View style={styles.card}><Text>Test4</Text></View>
<View style={styles.card}><Text>Test5</Text></View>
<View style={styles.card}><Text>Test6</Text></View>
<View style={styles.card}><Text>Test7</Text></View>
</View>
<View style={{width:"50%"}}>
<View style={styles.card}><Text>Testi</Text></View>
<View style={styles.card}><Text>Testii</Text></View>
<View style={styles.card}><Text>Testiii</Text></View>
<View style={styles.card}><Text>Testiv</Text></View>
<View style={styles.card}><Text>Testv</Text></View>
<View style={styles.card}><Text>Testvi</Text></View>
<View style={styles.card}><Text>Testvii</Text></View>
</View>
</View>
</ScrollView>
EDIT: also give height to card fixed instead of percentage because the view doesn't know what total size is so it cant calculate 20% exactly
see working eg. https://snack.expo.io/#jdgalani6297/scrolling-issue

Try below code:
<ScrollView style={{ flex: 1 }}>
<View style={{ flexDirection: 'row', flex: 1 }}>
<View style={{ flex: 0.5 }}>
<View style={styles.card}><Text>Test</Text></View>
<View style={styles.card}><Text>Test2</Text></View>
<View style={styles.card}><Text>Test3</Text></View>
<View style={styles.card}><Text>Test4</Text></View>
<View style={styles.card}><Text>Test5</Text></View>
<View style={styles.card}><Text>Test6</Text></View>
<View style={styles.card}><Text>Test7</Text></View>
</View>
<View style={{ flex: 0.5 }}>
<View style={styles.card}><Text>Testi</Text></View>
<View style={styles.card}><Text>Testii</Text></View>
<View style={styles.card}><Text>Testiii</Text></View>
<View style={styles.card}><Text>Testiv</Text></View>
<View style={styles.card}><Text>Testv</Text></View>
<View style={styles.card}><Text>Testvi</Text></View>
<View style={styles.card}><Text>Testvii</Text></View>
</View>
</View>
</ScrollView>
Card CSS:
NOTE : Don't forget to import Dimensions
card: {
height: (Dimensions.get('window').height * 0.20),
margin: 10,
borderWidth: 1,
borderColor: '#000',
borderStyle: 'solid',
}

Related

Divide the whole screen into four equal parts

I want to divide the whole screen into 4 equal parts each having a clickable action and onclick a prompt should appear with a textbox and an okay button on pressing it I need to render a webview
If you are doing this in react-native then use below code. This will divide screens in four parts and with TouchableOpacity you can use click events reflection otherwise you can use simple View.
<View style={{ flex: 1 }}>
<View style={{ flex: 1 }}>
<TouchableOpacity
style={{ flex: 1, backgroundColor: 'red' }}
onPress={() => { }} // Action
>
</TouchableOpacity>
<TouchableOpacity
style={{ flex: 1, backgroundColor: 'green' }}
onPress={() => { }} // Action
>
</TouchableOpacity>
</View>
<View style={{ flex: 1 }}>
<TouchableOpacity
style={{ flex: 1, backgroundColor: 'blue' }}
onPress={() => { }} // Action
>
</TouchableOpacity>
<TouchableOpacity
style={{ flex: 1, backgroundColor: 'yellow' }}
onPress={() => { }} // Action
>
</TouchableOpacity>
</View>
</View>
Yes, you can use common styling and components but for now I use separate So, you can easily edit and test.
You can use the vw(viewport width) and vh (viewport height), and assign to all of your items
width: "50vw",
height: "50vh"
<View style={{flex: 1}}>
<View style={{flex: 1}}> </View>
<View style={{flex: 1}}> </View>
</View>

warning each child in an array or iterator should have a unique key prop. react native

I have build React Native App and I face Problem for "Api" t did not give
me an error but i gives me a warring or Each items should have unique key I
didn't find any solution for how i solve this.
how to I use unique key in function
**
How to fix reactjs warning: each child in an array should have a unique prop…? 2**
<View style={styles.contanier}>
{this.props.data.map(function(videoData, index) {
console.log(videoData, "fetch3");
return (
<View style={styles.card_contanier}>
<TouchableOpacity
style={{ flex: 1 }}
// onPress={() => this.onforward()}
>
<View style={{ height: "45%" }}>
<Image
source={require("../img/special-page-banner.jpg")}
style={{
flex: 1,
width: imageWidth,
resizeMode: "stretch"
}}
/>
</View>
<View style={styles.title}>
<Text
style={{ color: "black" }}
numberOfLines={2}
ellipsizeMode={"tail"}
>
{videoData.name}
</Text>
</View>
<View style={{ height: "20%" }}>
<View style={styles.buttom_contanier}>
<View style={styles.logo}>
<Thumbnail
source={require("../img/andy-sm.png")}
style={{ height: 32, width: 32 }}
/>
</View>
<View style={{ flexDirection: "column" }}>
<View style={{ flexDirection: "row", left: 5 }}>
<Text
style={{ color: "black" }}
numberOfLines={1}
ellipsizeMode={"tail"}
>
{videoData.created_by_user.name}
</Text>
</View>
<View style={styles.iconic_contanier}>
<Icon name="calendar" size={10} style={{ top: 2 }} />
<Text style={styles.text}>10 Oct 2018</Text>
</View>
<View style={styles.iconic_contanier}>
<Icon name="eye" size={10} style={{ top: 2 }} />
<Text style={styles.text}>11 views</Text>
</View>
</View>
</View>
</View>
</TouchableOpacity>
</View>
);
})}
</View>
First and not the recommended approach will be tu use your index you get as second argument in your .map callback
<View style={styles.contanier}>
{this.props.data.map(function(videoData, index) {
console.log(videoData, "fetch3");
return (
<View key={index} style={styles.card_contanier}>
But using index is not recommended. If you have an id coming from your backend I will use it. This can cause problem with animation and thing like that if you use index.
<View style={styles.contanier}>
{this.props.data.map(function(videoData, index) {
console.log(videoData, "fetch3");
return (
<View key={videodata.id} style={styles.card_contanier}>
You can read about all this here https://reactjs.org/docs/lists-and-keys.html#keys
And article here about why not use index https://medium.com/#robinpokorny/index-as-a-key-is-an-anti-pattern-e0349aece318

React Native flexBox footer does not work

I searched how to set footer using React Native.
and I found a solution
https://stackoverflow.com/a/31249011/8226957
I followed and put style={{flex: 1}} to root View, but it does not work.
<View style={{flex: 1}}>
<ScrollView>
<FlatList
data={this.state.datas}
renderItem={({item}) =>
<TouchableOpacity onPress={() => {this._deleteKeyFromAsyncStorage(item.key)}}>
<Text style={styles.item}>
{item.value}
</Text>
</TouchableOpacity>
}
/>
</ScrollView>
<View>
<TextInput
style={{height: 40, borderColor: 'gray', borderWidth: 1}}
onChangeText={(text) => this.setState({text})}
value={this.state.text}
/>
<TouchableOpacity onPress={this._onAddButton}>
<View style={{
height: 50,
backgroundColor: 'steelblue',
alignItems: 'center',
justifyContent: 'center',
}}>
<Text style={{textAlign: 'auto'}}>ADD</Text>
</View>
</TouchableOpacity>
</View>
</View>
when I follow that, I see disappeared List.
Try to add justifyContent : 'space-between' and add flexDirection: 'column' that should be fix your problem
<View style={{flex: 1, flexDirection: 'column', justifyContent: 'space-between'}}>
Try to wrap the <ScrollView> in a <View style={{ flex: 1 }}>
If that does not work, try to set a fixed height too your footer: <View style={{ height: 90 }}>

React-Native Grid Style

With the following code:
<View style={{width:100,height:100,flexDirection:'row'}}>
<View style={{width:50, height:100}}>
a
</View>
<View style={{width:50, height:50}}>
b
</View>
<View style={{width:50, height:50}}>
c
</View>
</View>
--> I want to (IMAGE)
It is possible to do this with the "react-native-easy-grid" library.
However, it is possible to do this without using this library and with the above code structure. Without using rows and columns.
Can automatic placement be achieved by specifying only height and width values?
you can achieve this with flexbox:
<View style={{flex: 1, flexDirection:'row'}}>
<View style={{flex: 1, backgroundColor: 'red'}}>
<Text>a</Text>
</View>
<View style={{flex: 1, flexDirection:'column'}}>
<View style={{flex: 1, backgroundColor: 'green'}}>
<Text>b</Text>
</View>
<View style={{flex: 1, backgroundColor: 'blue'}}>
<Text>c</Text>
</View>
</View>
</View>

React Native: 2 scroll views with 2 sticky headers

I am trying to create a day-view with times on the left side, and a top header of people. Currently I can get the left OR the top header to stick, but not both.
How do you get 2 sticky headers?
My render looks like this:
<ScrollView style={{height: 600}}>
<ScrollView horizontal={true}>
<View style={styles.column}>
<View style={{ flex: 1, flexDirection: 'row', width}}>
{header}
</View>
<View style={styles.row}>
<View style={[styles.container, { width, marginLeft: 40 }]}>
{this.generateRows()}
</View>
</View>
</View>
</ScrollView>
<View style={{backgroundColor: 'white', position: 'absolute', top: 0, bottom: 0, left: 0, }}>
<View style={{ flex: 1, flexDirection: 'row'}}>
<View style={styles.row}>
<Text></Text>
</View>
</View>
<View style={{height: 1000, width: 40 }}>
{this.generateRowLabels()}
</View>
</View>
</ScrollView>
Can you try changing the top-level ScrollView to View/FlexBox with flexDirection as 'column'? This will cause the inner ScrollViews to fit into the window size.