ScrollView Refresh control is not visible when reload content from scrollview bottom - react-native

I have a scrollview which content is larger than phone screen.
I scroll to the bottom and there I have function that reload content of that scrollview but first clear data source for it.
Reload function is connected to RefreshControl on scrollview.
But RefreshControl is not visible while loading data except when I slightly touch screen where content should be.
And this is only when I start reload from scrollview bottom.
I tried to scroll to top but it doesn't solve it:
onContentSizeChange={(contentWidth, contentHeight) => {
this.scrollView.scrollTo({ y: 0 });
}}
Any idea why this is happening?
<ScrollView
ref={ref => (this.scrollView = ref)}
refreshControl={
<RefreshControl
refreshing={this.props.getDataInProgress}
onRefresh={this.reloadData.bind(this)}
/>
}
>
{this.renderData()}
renderData() {
return this.props.data.map((item, index) => {
return ... some function that return other components
So as I wrote if I pull down loader is visible.
But if I scroll to bottom and click one some button that call same function as pull to refresh loader is not visible.
EXAMPLE

Related

Nested ScrollView block parent scroll when started scrolling in child

I have a React Native app with a parent ScrollView component that wraps other 2 ScrollViews that are siblings. How could I force the parent to only scroll when I've started scrolling from outside the child components?
Current behavior:
When I start scrolling in a child, the child scrolls, but when the list reaches the end, the parent starts scrolling (finger was not removed from the screen, so it was the same scrolling action).
Desired behavior:
When I start scrolling in a child, the child scrolls, but when the list reaches the end, the parent does NOT scroll until I interrupt the current scrolling action and start scrolling again from the area of the parent.
You can't have nested scroll views in the same direction. You can try to improve the UI.
Even for the user this can be confusing.
Send a screenshot, so people can better understand what the goal is.
export const ScrollEnabledContext = createContext(null);
const Parent = () => {
const ref = useRef(null);
const setIsEnabled = (bool) => {
ref.current?.setNativeProps({ scrollEnabled: bool });
};
return (
<ScrollEnabledContext.Provider value={setIsEnabled}>
<ScrollView ref={ref} nestedScrollEnabled={true}>
<ChildScrollView />
</ScrollView>
</ScrollEnabledContext.Provider>
);
};
const ChildScrollView = () => {
const value = useContext(ScrollEnabledContext);
return (
<ScrollView onTouchStart={() => value(false)} onTouchEnd={() => value(true)}>
....
</ScrollView>
);
};

react-native-snap-carousel, snapToItem does not move the slider to a specific position when list length is more than 15 items

There is an image slider that contains more than 200 images there is a circular slider from which we slide that image slider. so we need to call the snapToItem method to move the carousel in a specific position. but snapToItem does not move the carousel to a specific position.
If the slider has only 10 or 15 images then it works perfectly but if we have more than 15 images snapToItem method doesn't work properly.
<Carousel
ref={carouselRef}
data={data}
renderItem={renderCarouselItem}
sliderWidth={width}
itemWidth={ITEM_WIDTH}
contentContainerCustomStyle={STYLES.paddingBottom10}
lockScrollWhileSnapping
onSnapToItem={index => setFocusedSliderIndex(index)}
containerCustomStyle={{
marginTop: heightToDp(10),
}}
enableMomentum
// scrollInterpolator={scrollInterpolator}
// slideInterpolatedStyle={animatedStyles}
/>
// we call the onUpdate function to move the slider using ciruclar-slider.
const onUpdate = () => {
// where we pass newIndex is dyanamic
if (carouselRef && carouselRef.current) {
carouselRef.current.snapToItem(newIndex);
}
};
Platform:- iOS/android (both)
react-native: 0.66.4,
react-native-snap-carousel: 3.9.1

Adjust the scrollview height dynamically at runtime

I am developing a react-native project.
I have a ScrollView in MyComponent, the content of ScrollView consists of :
a MySubComponent,
a Text
a Image component
All the content/data of above components have dynamic length or height. So, I would like adjust the content height of my ScrollView on the fly at runtime.
To achieve that my plan is to disable automaticallyAdjustContentInsets of the ScrollView as you can see from my below code snippet. Then, have a state variable to hold the latest value of contentInsetBottom. But I am not sure how can I calculate the height of child components so that I can call setContentInsetBottom(totalHeight) to update the content height of my ScrollView .
(I am pretty sure my plan will work if I know how to calculate the height of each child component of my ScrollView.)
Anyone can guide me a bit?
const MyComponent = ({myText, image}) => {
// I have a state of the contentInsetBottom for the ScrollView
const [contentInsetBottom, setContentInsetBottom] = useState(0);
// how can I get the height of each children component, sum them up & call setContentInsetBottom(totalHeight) here ?
return (
<ScrollView
automaticallyAdjustContentInsets={false}
contentInset={{top: 0, bottom: contentInsetBottom}}
style={styles.scrollView}
contentContainerStyle={styles.contentContainer}>
<MySubComponent />
<Text>{myText}</Text>
<Image source={{uri: image?.uri}}>
</ScrollView>)
}
Wrap all content inside the <ScrollView> in a <View>. Then use onLayout to get the height of that parent View.
const handleScrollContentLayout = (e) => {
const { height } = e.nativeEvent.layout
setScrollLayoutHeight(height)
}
...
<View onLayout={handleScrollContentLayout}>
{ /* scrollView content... */ }
</View>
Then you can use the scrollLayoutHeight as per your needs to set the height at runtime.

Is there a way to get the swipe progress of react-native-swiper?

I would like to have an event like onScroll on the ScrollView but onSwipe on the Swiper. And in this callback I would like to get the "swipe progress" (e.g. swiped 50% to the second item). With all the supported callbacks I can do something when the swipe starts or ends but I also want all the steps in between. How could I do this?
To get the scrolled position of the current view
Swiper component is a ScrollView and you can use its native props with Swiper as well, for your case use onScroll prop to get where the scroll is and the percentage swipped.
const viewWidth = Dimensions.get('window').width;
...
<Swiper
scrollEventThrottle={16}
onScroll={(e) =>
const scrolledPercentage =(e.nativeEvent.contentOffset.x / (viewWidth * (this.currentIndex + 1)));
}
>
...
</Swiper>
.
To get the progress of your passed views
Just get the current index with onIndexChanged props and then calculate your progress with the count of your Views inside of the swiper
<Swiper
style={styles.wrapper}
showsButtons={true}
onIndexChanged={(index) => {
let progress= index/totalNumberOfView
let progressInPercentage = Math.floor(progress*100)
this.setState({
progress,
progressInPercentage
})
}
>

Get current scroll position of FlatList

I have this code:
<FlatList
ref={(x) => (this.flatList = x)}
data={players}
style={this.props.style}
/>
What I need is to save the current scroll position of the FlatList when the user e.g. navigates away.
So something like this.flatList.getCurrentScrollPosition().
Is there such a thing?
FlatList inherits all of ScrollView props. Therefore you can use onScroll.
onScroll = (event) => {
const scrollOffset = event.nativeEvent.contentOffset.y
}