I have a View like this
<View style={styles.columnView}>
<View style={[styles.columnButtonItem, styles.columnC]}><Text></Text></View>
<View style={[styles.columnButtonItem, styles.columnA]}><Text></Text></View>
<View style={[styles.columnButtonItem, styles.columnB]}><Text></Text></View>
<View style={[styles.columnButtonItem, styles.columnE]}><Text>{value}</Text></View>
<View style={[styles.columnButtonItem, styles.columnAs]}><Text></Text></View>
<View style={[styles.columnButtonItem, styles.columnT]}><Text></Text></View>
</View>
After iterations, I compose a table like this:
There is a way to add ScroolView on a single column?
For example, I want to enable scroll only on columnE.
Obviously, when i scroll columnE I want to scroll all the table.
Thanks
Absolutely positioned Views
If you know the width of the columns then you could use Views that are absolutely positioned that overlap the underlying ScrollView, they would stop all touches to the ScrollView. Meaning that it would only scroll on the part that isn't covered by the absolutely positioned views.
So you could do something like this
render() {
// set these widths to be the size before row E and the size after row E
let leftWidth = '33%';
let rightWidth = '33%';
return (
<View style={{flex: 1}}>
<ScrollView style={{flex: 1}}>
// items for the scroll view go here
</ScrollView>
<View style={{position:'absolute', top:0, left: 0, bottom: 0, width: leftWidth}} />
<View style={{position:'absolute', top:0, right: 0, bottom: 0, width: rightWidth}} />
</View>
)
}
Snack
Here is a snack showing this implementation. I have set a backgroundColor on the absolutely positioned views so that you can clearly see them.
https://snack.expo.io/#andypandy/partial-scrollview
Caveat
The main problem with this solution is that you will not be able to touch anything that is below the absolutely positioned views. You could mitigate that by capturing touches using gestures on each View and then mapping them to positions on the ScrollView.
I (think) this is what you're looking for... essentially you can only scroll the far right column and the rest of the columns are not scrollable. Because of that, you have to wait for the native event handler of ScrollView to propagate any change before you render the fact that the rest of those 4 columns are scrolling though.
https://snack.expo.io/#vincentvella/scroll-example
Related
I'm building a small eCommerce app in React Native and when the customer adds something to their cart I want to display a "View cart" TouchableOpacity at the bottom of the screen until they clear the cart.
This is what I'm returning on each page, along with styling:
return (
<TouchableOpacity
style={styles.cartView}
onPress={() => navigation.navigate('View Cart')}>
<Text style={styles.cartText}>View cart</Text>
</TouchableOpacity>
);
cartView: {
justifyContent: 'center',
alignItems: 'center',
maxHeight: 50,
minWidth: '100%',
alignSelf: 'center',
marginTop: 50,
backgroundColor: '#373F51',
padding: 10,
top: 40,
borderRadius: 20,
},
When I'm on a page that isn't scrollable this works fine and it appears right above the tab navigator. However, when I try and render this on a scrollable page, like one with a FlatList, things get messy. It either lays directly on top of the component below it or you'll have to scroll to the bottom of the screen to see it if it's placed at the bottom of the component tree.
How can I change my styling so that it renders at the bottom of the page and stays there in one spot (I'm fine with it covering the content behind it)?
You may try to refer to this article.
The main concept is using position: 'absolute' and bottom: 0 to do the trick. This will force component render by absolute position instead of flex.
I'm trying to get ScrollView to Scroll horizontally only when sliding a particular view
something like this:
<ScrollView horizontal={true}>
<View style={styles.TopView}></View>
<View style={styles.BottomView} Scrollable={false}></View>
</ScrollView>
I was thinking of disabling the scroll OnPressIn using hooks like this:
const [Scrollmove, setScrollmove] = useState(true);
<ScrollView horizontal={true} scrollEnabled ={Scrollmove}>
<View style={styles.TopView}></View>
<Pressable
onPressIn={()=>{setScrollmove(false)}}
onPressOut={()=>{setScrollmove(true)}}>
<View style={styles.BottomView}></View>
</Pressable>
</ScrollView>
but I don't know if it would work and is there a better way to achieve the desired effect?
Note: the code segments I've written above are pseudo code
You can't do that. However, you can change your design like, divide your screen and half of it can be scroll, other half can stay.
<View style={styles.TopView}>
<Text>Stay</Text>
</View>
<ScrollView horizontal={true}>
<View style={styles.BottomView} Scrollable={false}>
<Text>Scrollable</Text>
</View>
</ScrollView>
Hy, I'm new in react-native. I'm stuck in the flatlists and scrollView. Here's the structure of my code:
<View>
<ScollView>
<View>
<SafeAreaView>
<FlatList/> -- Horizontal Scroll --
</SafeAreaView>
</View>
<View>
</View>
<View>
<FlatList/> -- Horizontal Scroll --
</View>
<View>
<FlatList/> -- Horizontal Scroll -- //Issue
</View>
</ScollView>
</View>
So the issue flatlist mentioned above like //Issue. The issue is that when I add the flatlist which is need to scroll in vertical format its not scrolling and one more thing this flatlist is displaying at the middle of screen so to start the working I add the height and its start working but the functionality I want is that When I scroll the screen should move to down. So do this i add the scrollView as you in above structure but when I add scrollView I remove the height it start working perfectly but displaying that error:
VirtualizedLists should never be nested inside plain ScrollViews with the same orientation because it can break windowing and other functionality - use another VirtualizedList-backed container instead.
So to solved this I try:
nestedScrollEnable={true}
scrollEnabled
giving height
When I start working on this app I also face same issue then I get the solution using ListHeaderComponent and ListFooterComponent. But now my already code in Header and Footer component.
but I can't solve. If some have some idea then share it. I would appreciate your favor
As per the React-Native, it is not ideal to use FlatList inside the ScrollView. What you can do instead is, to use nested scroll view. The only thing which is going to be changed is you have to do .map(), and populate the data inside the ScrollView inspite of renderItem from FlatList, and every thing will else will work just fine.
Use flexGrow: 1, inside the ScrollView, then no height is required.
Your Structure now should be:
<View style={{flex: 1}} >
<ScollView style={{flexGrow: 1}}
nestedScrollEnabled={true}>
<View>
<SafeAreaView>
<ScrollView horizontal
style={{width: '100%', height: 'your_height'}}>
{data.map(item, index) => (
<View key={index}>
// Your component
</View>
)}
</ScrollView> -- Horizontal Scroll --
</SafeAreaView>
</View>
<View>
</View>
<View>
<ScrollView horizontal
style={{width: '100%', height: 'your_height'}}>
{anotherData.map(item, index) => (
<View key={index}>
// Your component
</View>
)}
</ScrollView> -- Horizontal Scroll --
</View>
<View>
<ScrollView horizontal
style={{width: '100%', height: 'your_height'}}>
{newData.map(item, index) => (
<View key={index}>
// Your component
</View>
)}
</ScrollView> -- Horizontal Scroll --
</View>
</ScrollView>
</View>
I have a ScrollView which content doesn't necessarily exceeds it's size. Let's say it's a form where, upon errors, it expands to add error messages and then it exceeds the ScrollView size and thus is why I'm using that scroll.
The thing is that I want the content to always be at least of the same size of the ScrollView. I'm aware of the minHeight property, but the only way I found to use it is re-rendering, which I'd like to avoid.
I'm using redux for state management and this is what I have
<ScrollView
contentContainerStyle={[ownStyles.container, {minHeight: this.props.scrollHeight}]}
style={this.props.style}
showsVerticalScrollIndicator={false}
onLayout={(event) => {
scrollHeight = event.nativeEvent.layout.height;
this.props.setScrollContentHeight(scrollHeight);
}}
>
Where the this.props.setScrollContentHeight triggers an action which enters the height on the state, and this.props.scrollHeight is said height. So that after the first render where the onLayout function is triggered, the state is updated with the ScrollView's height, which I then assign as minHeight to its content.
If I set the content's style to flex: 1 then the ScrollView won't scroll.
Can you think of a way to avoid that second render for performance purposes?
Thank you!
You should use flexGrow: 1 for the ScrollView and flex: 1 inside the ScrollView, to get a ScrollAble but at least as big as possible <View>.
There has been a discussion about it in react-native and tushar-singh had the great idea to it.
It has been a long time but I struggled with the same issue. The easy way to do it is to use flexGrow: 1 instead of flex:1 on both scrollView's style and contentContainerStyle props. The content will take at least 100% of space and more if needed.
A couple of solutions of doing this are:
Use a minHeight on the ScrollView (but this requires taking into account the screen dimension to render correctly)
Use a flexGrow: 1 on the ScrollView contentContainerStyle and a flex: 1 to the inner content:
<ScrollView contentContainerStyle={{ flexGrow: 1 }}>
<View style={{ flex: 1 }}>
...
</View>
</ScrollView>
i want to share my solution, for me nothing of https://github.com/facebook/react-native/issues/4099 worked. Also i cannot comment there because facebook blocked the thread ¬.¬ !
Basically my solution is set flexGrow: 1 in contentContainerStyle on the ScrollView component, and wrap all the content inside in a View component with a height property setted with the screen size. Here the example code:
import { Dimensions } from "react-native";
let screenHeight = Dimensions.get('window').height;
<ScrollView contentContainerStyle={{ flexGrow: 1 }}>
<View style={{height: screenHeight}}>
... your content here ...
</View>
</ScrollView>
I know this is a little late, but I think wrapping the contents inside of that ScrollView with a View with minHeight style property will do the trick.
<ScrollView contentContainerStyle={{ flexGrow: 1 }}>
<View style={{ flexGrow: 1 }}>
Your content
</View>
</ScrollView>
That worked for me.
I'm trying to display a list of rows in a React Native ListView, but it only shows the entries that fit in a single screen, ie, I can't scroll down to see more rows.
Here are the styles:
styles = StyleSheet.create({
container: {
flex: 1,
marginTop: 60
},
rowContainer: {
flexDirection: 'row',
justifyContent: 'space-around'
}
})
ListView:
return (
<View style={styles.container}>
{this.getHeader()}
<ListView
dataSource = {this.state.dataSource}
renderRow = {this.renderRow.bind(this)}/>
</View>
)
Row:
return (
<View style={styles.rowContainer}>
<Text>{text}</Text>
</View>
)
What am I doing wrong?
I had the same issue and found that Listview with wrapper View outside will make ListView not scrollable.
The workaround will be removing wrapper View:
return (
<ListView
dataSource = {this.state.dataSource}
renderRow = {this.renderRow.bind(this)}/>
)
I'll post this here in spite of the OP already having found a solution b/c my ListView wouldn't scroll either and it wasn't b/c I was trying to scroll rather than using the mouse to simulate swiping. I am currently using React-Native v0.1.7.
It turned out that the reason my ListView wouldn't scroll & wouldn't reveal the other rows which weren't being initially rendered on screen was that it didn't have a fixed height. Giving it a fixed height solved this issue. Figuring out how to determine what value to use for the height wasn't a simple matter though.
In addition to the ListView on the page there was also a header at the top of the page which had a fixed height. I wanted that ListView to take up the remaining height. Here, either my ability to use the React-Native limited implementation of FlexBox failed me or the implementation did. However, I was unable to get the ListView to fill up the remainder of the space and be able to scroll properly.
What I did was to require the Dimensions package const Dimensions = require('Dimensions'); and then set a variable for the device window's dimensions const windowDims = Dimensions.get('window'); Once I had that done I was able to determine the height of the remaining space and apply that inline to the style of the ListView: <ListView style={{height: windowDims.height - 125}} ... /> where 125 was the height of the header.
What worked for me was to follow this response: https://stackoverflow.com/a/31500751/1164011
Basically, I had
<View>
<ListView/>
</View>
And what was happening was that the <View> component was getting a height of 0. So I needed to update it to:
<View style={{ flex: 1 }}>
<ListView/>
</View>
That way <View> gets its height based on the content.
Wrap listview and other contents in scroll view.. That solved my scroll issue.
ListView contains an inner ScrollView so it should work as is. On the simulator your scroll by clicking and dragging the mouse.
Why don't you show the full code, maybe some screenshots?