Is there any way to get height of whole ScrollView element in React Native?
return (
<View ref='container' style={[ styles.container, backgroundColor, {width: this.props.width} ]}>
<ScrollView ref='scroll' style={styles.scrollView}> --> what height with inner content?
{this._getTitle()}
<View style={styles.content}>
{items}
</View>
<View style={[styles.empty]} />
</ScrollView>
</View>
)
I don't know if this is an officially documented API, but getting the content size can be done using the native scroll-view manager.
Add the necessary imports:
import ReactNative, {NativeModules} from 'react-native';
const ScrollViewManager = NativeModules.ScrollViewManager;
Call this in your code at a point where you already have access to the scrollview ref:
if(ScrollViewManager && ScrollViewManager.getContentSize) {
ScrollViewManager.getContentSize(ReactNative.findNodeHandle(this.scrollViewRef), (contentSize) => {
console.log(contentSize);
})
}
Related
i got an problem with the refreshing on pull function. The FlatList renders fine, but pull to refresh is not working. This is my current sourcecode:
return (
<View style={GlobalStyles.flex1}>
<FlatList
showsVerticalScrollIndicator={false}
refreshControl={
<RefreshControl
refreshing={isRefreshing}
onRefresh={() => {
console.log("onRefresh loadVocable");
loadVocables();
}}
/>
}
data={vocables}
keyExtractor={vocable => vocable.id}
onEndReached={() => {
if (!isRefreshing && !endReached) {
loadVocables();
}
}}
renderItem={vocable => (
<TouchableOpacity
onPress={() => {
props.navigation.navigate({ routeName: "editVocable", params: { vocable: vocable.item } });
}}
onLongPress={() => {
handleLongPress(vocable.item.id);
}}>
<Card style={styles.cardStyle}>
<View style={styles.part1}>
<Text style={styles.vocableText}>{vocable.item.wordENG}</Text>
<Text style={styles.vocableText}>{vocable.item.wordDE}</Text>
</View>
<View style={styles.part2}>
<Ionicons name={vocable.item.known ? "md-checkmark-circle" : "md-close-circle"} size={23} color={vocable.item.known ? Colors.success : Colors.danger} />
</View>
</Card>
</TouchableOpacity>
)}
/>
</View>
);
In the official docs is an example that says contentContainerStyle needs to be flex: 1 to know the height, that makes sence to me, so when i set contentContainerStyle with flex 1, refresh on pull works fine, but then i can't scroll anymore in the Flatlist and everthing get very tight, so the style also change then. Does anyone know why this happen?
The first picture is with "contentContainerStyle={{flex: 1}}" and the last one is without contentContainerStyle.
The answer was so easy, I compared a new project (there worked my code) to the one where the problem was and after 5 days I found the little error:
My import was wrong!
I imported FlatList like this:
import { FlatList } from "react-native-gesture-handler";
But it needs to get imported from React-Native so like this:
import { FlatList } from "react-native";
Thanks to #The1993, without the hint to compare the projects, maybe I would stuck forever on this error :D In the future I will compare working files to find any error!
contentContainerStyle is used to style inner content e.g items alignments, padding, etc
style is used to align its height and relations
You can replace style={{flex: 1}} instead of contentContainerStyle or wrap the parent element with flex: 1
I have a structure like this:
<View style={container}>
<View style={first}></View>
<View style={second}><View>
<View style={third}</View>
</View>
The container pretty much fills the whole screen.
When the user touches the container and moves the finger around without lifting the finger, I would like to know which View the finger is currently placed at.
Use TouchableWithoutFeedback to wrap around your views, and then you can call the onPressIn function to detect touch event.
You cannot detect the touched view unless and until you don't have any touch event on it.
To do that you can use TouchableOpacity (respond to the press and have visual feedback when touched.) or TouchableWithoutFeedback (it won't show any visual feedback when touched)
Below is the sample example as required:
import React, { Component } from 'react'
import {
TouchableOpacity,
View
} from 'react-native'
export default class SampleComponent extends Component {
constructor(props) {
super(props)
}
_onPressView = (viewName) => {
console.log("Tapped View ===> ", viewName)
}
render() {
return (
<View style={styles.container}>
<TouchableOpacity onPress={() => this._onPressView("FirstView")}>
<View style={styles.first}/>
</TouchableOpacity>
<TouchableOpacity onPress={() => this._onPressView("SecondView")}>
<View style={styles.second}/>
</TouchableOpacity>
<TouchableOpacity onPress={() => this._onPressView("ThirdView")}>
<View style={styles.third}/>
</TouchableOpacity>
</View>
);
}
}
I have this code:
<View style={{flex:1}}>
<ScrollView>
<View style={{flex:0.25,elevation:2,marginVertical:5}}>
<MoviesChild/>
</View>
<View style={{flex:0.75}}>
<FlatList
data={ListOfMovies}
renderItem={this.renderData.bind(this)}
keyExtractor={(x, i) => x.id}
extraData={this.state}
/>
</View>
</ScrollView>
</View>
The problem is, my FlatList's data appears but my child component MoviesChild disappears. Maybe Flatlist overlaps the child component. Could someone figure out where I'm doing a mistake please?
You should give style to ScrollView with flexGrow:1
I suggest you not to use FlatList inside a ScrollView, 'cause FlatList scroll itself. So, in order to achieve your objective, wrap your first View in a function and pass it to the ListHeaderComponent property of your FlatList, like this:
<View style={{flex:1}}>
<View style={{flex:0.75}}>
<FlatList
data={ListOfMovies}
renderItem={this.renderData.bind(this)}
keyExtractor={(x, i) => x.id}
extraData={this.state}
ListHeaderContainer={this.renderHeader}
/>
</View>
</View>
where
private renderHeader = () => {
return(
<View style={{flex:0.25,elevation:2,marginVertical:5}}>
<MoviesChild/>
</View>
)
}
I hope this can fix your issue!
You can find what I'm talking about on the official doc
Try this,
<View style={{flex:1}}>
<View style={{ flex:0.25,elevation:2,marginVertical:5 }}>
<MoviesChild/>
</View>
<FlatList
style={{flex:0.75}}
data={ListOfMovies}
renderItem={this.renderData.bind(this)}
keyExtractor={(x, i) => x.id}
extraData={this.state}
/>
</View>
I am using the react-native-chart module to display charts in my app, and I wanted to add a touchable functionality to the the plotted dots on the chart, so I went into the library and tried to wrap this with a <TouchableOpacity> component: https://github.com/tomauty/react-native-chart/blob/master/src/LineChart.js#L168
When I tried running my app, I get these errors from xcode:
Reproduction
By Installing the react-native-chart module directly from github, then trying to wrap this with TouchableOpacity https://github.com/tomauty/react-native-chart/blob/master/src/LineChart.js#L168
return (
<View>
<View style={{ position: 'absolute' }}>
<Surface width={containerWidth} height={containerHeight}>
{ multipleLines }
{ multipleFills }
</Surface>
</View>
<View style={{ position: 'absolute' }}>
<Surface width={containerWidth} height={containerHeight} />
</View>
{(() => {
if (!this.props.showDataPoint) return null;
var multipleDataPoints = dataPoints.map( (dataPointSet, index) => {
let totalDataSet = dataPointSet.map((d, i) => {
return (
// <TouchableOpacity>
<Circle key={i} {...d} onPress={()=>alert(i)} />
// </TouchableOpacity>
);
});
return totalDataSet;
});
return (
<Surface width={containerWidth} height={containerHeight}>
{ multipleDataPoints }
</Surface>
);
})()}
</View>
);
Additional Information
React Native version: 0.39.2
Platform: iOS
Operating System: MacOSX 10.12.2
You cannot add Circle component inside TouchableOpacity. ReactArt expects Surface component children to be instance ARTNode in native side. You can try sending pandresponder properties to Circle component. From reading core code, it seems that should work. I haven't tried it on ReactArt by myself yet.
Here is my render function of react native. if i put listview it works. if i put touchablehighlight it works. but, if it put both it doesn't work. need help.
render: function() {
return (
/* ListView wraps ScrollView and so takes on its properties.
With that in mind you can use the ScrollView's contentContainerStyle prop to style the items.*/
<ListView
contentContainerStyle={styles.list}
dataSource={this.state.dataSource}
renderRow={this._renderRow}/>
<TouchableHighlight onPress={() => this._pressRow(rowID)} underlayColor="transparent">
</TouchableHighlight>
);
},
what is wrong here? need both components to work.
You can't have 2 tags that you can return. You should wrap it inside a <View> </View> tag. This way you can abstract multiple components that you need in the page.
render: function() {
return (
/* ListView wraps ScrollView and so takes on its properties.
With that in mind you can use the ScrollView's contentContainerStyle prop to style the items.*/
<View>
<ListView
contentContainerStyle={styles.list}
dataSource={this.state.dataSource}
renderRow={this._renderRow}/>
<TouchableHighlight onPress={() => this._pressRow(rowID)} underlayColor="transparent">
</TouchableHighlight>
</View>
);
},
Hope it helps.