Closed Bardiamist closed 3 years ago
@Bardiamist Could you provide more description ?
Simular issue was on on iOS when ViewPager was introdused on iOS. And you fixed that.
I have 3 pages. Every page has FlatList. Every Flat list row is TouchableOpacity. On scroll end fires onPress of TouchableOpacity.
This snippet https://github.com/react-native-community/react-native-viewpager/issues/73#issuecomment-562950417 should be also applied for android ?
Could you provide code example, that I can check for android ?
Do you know, if issue exist for < 4.0.0 ?
Only on 4.0.0. I updated, tested, saw it bug, and rolled back to 3.3.0.
Same here, but not only on scroll end, I'm also having the same issue when swiping left or right on Android. I moved back to 3.3.0, and it's working fine.
When I say "scoll end", I mean swiping left or right.
Same issue, if a page has TouchableOpacity inside, it fires onPress of that TouchableOpacity every swipe that is touching that touchable. v3 works good.
@lukebars @Bardiamist is it somehow related to https://github.com/react-native-community/react-native-viewpager/issues/11 ?
I started investigation here: https://github.com/react-native-community/react-native-viewpager/tree/164
Probably I found a solution.
the same issue, is there any update for this? I moved back to 3.3.0, and it's working fine
same here downgrade to 3.3.0 and everything is working fine
yep same here: ViewPager v4 with touchable items will trigger onPress() when scrolling. Worked fine on v3.3 only tested on Android
I had this issue on android, while iOS was perfectly fine.
The solution is to use TouchableOpacity component from react-native-gesture-handler
.
import { TouchableOpacity } from 'react-native-gesture-handler'
It handles touches / gestures in a bit different way:
These touchables and their feedback behavior are deeply integrated with native gesture ecosystem and could be connected with other native components (e.g. ScrollView) and Gesture Handlers easily and in a more predictable way, which follows native apps' behavior.
same
guys any solution for this problem?
+1
@troZee did you manage to solve this?
import { TouchableOpacity } from 'react-native-gesture-handler'
doesn't work for me, it makes the view pager un-swipeable
Downgraded to 3.3.0, it works fine
Using a FlatList with Viewpager 4.0+ on Android makes scrolling unusable. Trying to scroll down and it constantly "steals away" the scroll event and scrolls left / right. Going back to 3.3.0 is working fine. However the 3.x has this issue on iOS which wants me to upgrade..
For example using react-native-pdf to show a PDF (which uses a FlatList). Its nearly unscrollable on Android in 4.0+, however totally fine on 3.3.0.
I had this issue on android, while iOS was perfectly fine.
The solution is to use TouchableOpacity component from
react-native-gesture-handler
.import { TouchableOpacity } from 'react-native-gesture-handler'
It handles touches / gestures in a bit different way:
These touchables and their feedback behavior are deeply integrated with native gesture ecosystem and could be connected with other native components (e.g. ScrollView) and Gesture Handlers easily and in a more predictable way, which follows native apps' behavior.
I have this scrolling and touching conflict issue on iOS. I use above method to fix it on iOS and later discover these touchables from react-native-gesture-handler don't working on Android currently. see https://github.com/software-mansion/react-native-gesture-handler/issues/578
at the end, I have to do below : (
import { Platform } from 'react-native';
let TouchableHighlight,TouchableOpacity;
if (Platform.OS === 'ios') {
({ TouchableHighlight,TouchableOpacity } = require('react-native-gesture-handler'));
} else {
({ TouchableHighlight,TouchableOpacity } = require('react-native'));
}
I'm having this problem too, only in android. Looks like @troZee commit worked for me, i'll test it more thoroughly to make sure it solved the problem and reply here later.
update: After more testing i've encountered many other problems after testing with @troZee fix. I'm using FlatList from RN now and it's working fine.
Same issue good work in v 3.3.1 on android , v4 if use TouchableHighlight from gesture handler hot work swipe scroll tabs, if from react-native swipe scroll handled onPress on flatlist item on android and ios (ios have this bug too on real device emulator not reproduce, but small count incident rundom triger onPress in v3.3.1 and latest v4) my solution not use this library until this problem is resolved
Can someone test above PR ?
After more testing i've encountered many other problems after testing with @troZee fix.
What problems @felipeViana ?
@troZee
github:react-native-community/react-native-viewpager#@troZee/fix-on-scroll
doesn't seem to fix the problem.
Could you provide a code snippet, which I can test ?
@troZee Just a FlatList full of big TouchableOpacity's navigating to other screen. I can't provide a working code snippet right now, but if you won't be able to reproduce it, I could take some time to prepare one.
@lukebars can you also check the v. 3.3.0 ?
@troZee We're using 3.3.0
in prod right now and that works like a charm.
I can confirm the PR does not work. v3.3.1 is fine.
@troZee you can test it using this snippet. Try to scroll the pdf on the second page on Android. Best of luck :+1: This works fine in v3.3.1, however using v4.x makes it unscrollable. iOS is totally fine on both versions. react-native-pdf uses a FlatList in the background.
App.js
import React from "react";
import { StyleSheet, Dimensions, View, Text } from "react-native";
import ViewPager from "@react-native-community/viewpager";
import Pdf from "react-native-pdf";
const App = () => {
const source = {
uri: "http://samples.leanpub.com/thereactnativebook-sample.pdf",
cache: true,
};
//const source = require('./test.pdf'); // ios only
//const source = {uri:'bundle-assets://test.pdf'};
//const source = {uri:'file:///sdcard/test.pdf'};
//const source = {uri:"data:application/pdf;base64,JVBERi0xLjcKJc..."};
return (
<ViewPager style={styles.viewPager} initialPage={0}>
<View key="1">
<Text>First page</Text>
</View>
<View key="2" style={styles.container}>
<Pdf source={source} style={styles.pdf} />
</View>
</ViewPager>
);
};
const styles = StyleSheet.create({
viewPager: {
flex: 1,
},
container: {
flex: 1,
justifyContent: "flex-start",
alignItems: "center",
marginTop: 25,
},
pdf: {
flex: 1,
width: Dimensions.get("window").width,
height: Dimensions.get("window").height,
},
});
export default App;
Package.json
"dependencies": {
"react": "16.13.1",
"react-native": "0.63.2",
"react-native-pdf": "6.2.0",
"@react-native-community/progress-bar-android": "1.0.3",
"@react-native-community/progress-view": "1.1.1",
"@react-native-community/viewpager": "4.1.6",
"rn-fetch-blob": "0.12.0"
},
After more testing i've encountered many other problems after testing with @troZee fix.
What problems @felipeViana ?
I'm using react-native-tab-view
to render tabs at home screen and some internal screens as well.
The tab content at home would be blank after going in the internal tab screens then going back to home.
Other people tested and related different problems but i ended up going for another solution and didn't try to find the root cause for these problems.
Bug
Content touches on scroll end on Android (tested on Android 5.0)
Similar issue was on on iOS when ViewPager was introduced on iOS. And you fixed that.
I have 3 pages. Every page has FlatList. Every Flat list row is TouchableOpacity. On scroll end fires onPress of TouchableOpacity.
Library version: 4.0.0 breaks it. It works on < 4.0.0
I do found a workaround to fix it
I changed my initial structure - ViewPager as father with FlatList - as as so as my father component is a flatlist. I did that because i can use flatlist onScroll props to disable touch from rendered items. You can use this idea to do what you want, since FlatList has really powerfull with props
const [disabledTouch, setDisabledTouch] = useState(false)
return (
<FlatList
data={data}
// fires when user begin/end drag
// you can use other props, such as onMomentumScroll etc
onScrollBeginDrag={() => setDisabledTouch(true)}
onScrollEndDrag={() => setDisabledTouch(false)}
renderItem={({ item }) => (
<>
<ViewPager> {item.map() ....}</ViewPager>
<TouchableWithoutFeedback disabled={disabledTouch} />
</>
)}
/>
)
I hope this gets fixed soon, I am uncomfortable using 2 different TouchableOpacity for iOS and Android
when fixed this issue?
I found a solution ref this comment https://github.com/react-native-community/react-native-viewpager/issues/73#issuecomment-562950417
<ViewPager
onMoveShouldSetResponderCapture={() => true}
>
// ... your content
</ViewPager>
and if you are using FlatList
or ScrollView
with ViewPager
change
import { FlatList } from 'react-native'
to
import { FlatList } from 'react-native-gesture-handler'
Thank you @ljsalm089 @Fortidude
I was able to solve this by wrapping
ViewPager in <NativeViewGestureHandler disallowInterruption={true}>
from react-native-gesture-handler
E.g.
import { NativeViewGestureHandler } from 'react-native-gesture-handler';
<NativeViewGestureHandler
disallowInterruption={true}>
<ViewPager>
{children}
</ViewPager>
</NativeViewGestureHandler>
This is how FlatList exported from react-native-gesture-handler works as well.
Updating to v4.2.x seems to fix this issue for me.
Based on the release notes, the Android version was reverted to the latest stable codebase (v3.3.0).
@elkinjosetm Yep, but a problem still remain on next version
This issue has been fixed in 5.0.5
"react-native-pager-view": "^5.1.7"
Have this problem on iOS and android
Hi! 👋
Firstly, thanks for your work on this project! 🙂
Today I used patch-package to patch react-native-pager-view@5.4.0
for the project I'm working on.
Here is the diff that is a workaround for the problem with too sensitive swiping on android (source: https://medium.com/@al.e.shevelev/how-to-reduce-scroll-sensitivity-of-viewpager2-widget-87797ad02414)
The proper fix I guess would be https://bladecoder.medium.com/fixing-recyclerview-nested-scrolling-in-opposite-direction-f587be5c1a04. But it hasn't made to android repo yet.
diff --git a/node_modules/react-native-pager-view/android/src/main/java/com/reactnativepagerview/PagerViewViewManager.kt b/node_modules/react-native-pager-view/android/src/main/java/com/reactnativepagerview/PagerViewViewManager.kt
index 6e2a436..7c757be 100644
--- a/node_modules/react-native-pager-view/android/src/main/java/com/reactnativepagerview/PagerViewViewManager.kt
+++ b/node_modules/react-native-pager-view/android/src/main/java/com/reactnativepagerview/PagerViewViewManager.kt
@@ -1,6 +1,7 @@
package com.reactnativepagerview
import android.view.View
+import androidx.recyclerview.widget.RecyclerView
import androidx.viewpager2.widget.ViewPager2
import androidx.viewpager2.widget.ViewPager2.OnPageChangeCallback
import com.facebook.infer.annotation.Assertions
@@ -24,6 +25,17 @@ class PagerViewViewManager : ViewGroupManager<ViewPager2>() {
return REACT_CLASS
}
+ fun ViewPager2.reduceDragSensitivity(value: Int) {
+ val recyclerViewField = ViewPager2::class.java.getDeclaredField("mRecyclerView")
+ recyclerViewField.isAccessible = true
+ val recyclerView = recyclerViewField.get(this) as RecyclerView
+
+ val touchSlopField = RecyclerView::class.java.getDeclaredField("mTouchSlop")
+ touchSlopField.isAccessible = true
+ val touchSlop = touchSlopField.get(recyclerView) as Int
+ touchSlopField.set(recyclerView, touchSlop*value)
+ }
+
override fun createViewInstance(reactContext: ThemedReactContext): ViewPager2 {
val vp = ViewPager2(reactContext)
vp.adapter = ViewPagerAdapter()
@@ -134,6 +146,11 @@ class PagerViewViewManager : ViewGroupManager<ViewPager2>() {
}
}
+ @ReactProp(name = "scrollSensitivity", defaultInt = 2)
+ fun setScrollSensitivity(viewPager: ViewPager2, value: Int) {
+ viewPager.reduceDragSensitivity(value)
+ }
+
@ReactProp(name = "orientation")
fun setOrientation(viewPager: ViewPager2, value: String) {
viewPager.orientation = if (value == "vertical") ViewPager2.ORIENTATION_VERTICAL else ViewPager2.ORIENTATION_HORIZONTAL
diff --git a/node_modules/react-native-pager-view/lib/typescript/types.d.ts b/node_modules/react-native-pager-view/lib/typescript/types.d.ts
index e14b01b..a67a19b 100644
--- a/node_modules/react-native-pager-view/lib/typescript/types.d.ts
+++ b/node_modules/react-native-pager-view/lib/typescript/types.d.ts
@@ -4,6 +4,7 @@ export declare type TransitionStyle = 'scroll' | 'curl';
export declare type Orientation = 'horizontal' | 'vertical';
export declare type OverScrollMode = 'auto' | 'always' | 'never';
export declare type PageScrollState = 'idle' | 'dragging' | 'settling';
+export type ScrollSensitivity = 2|3|4|5|6|7|8;
export declare type PagerViewOnPageScrollEvent = ReactNative.NativeSyntheticEvent<PagerViewOnPageScrollEventData>;
export interface PagerViewOnPageScrollEventData {
position: number;
@@ -28,6 +29,13 @@ export interface PagerViewProps {
* The default value is true.
*/
scrollEnabled?: boolean;
+ /**
+ * Higher the `scrollSensitivity` value, more the effort to swipe.
+ * Adjust multiplier from 2-8 until you find the sweet spot.
+ *
+ * Only supported on Android.
+ */
+ scrollSensitivity?: ScrollSensitivity;
/**
* Executed when transitioning between pages (ether because of animation for
* the requested page change or when user is swiping/dragging between pages)
diff --git a/node_modules/react-native-pager-view/src/types.ts b/node_modules/react-native-pager-view/src/types.ts
index 72cf02c..13e6be1 100644
--- a/node_modules/react-native-pager-view/src/types.ts
+++ b/node_modules/react-native-pager-view/src/types.ts
@@ -5,6 +5,7 @@ export type TransitionStyle = 'scroll' | 'curl';
export type Orientation = 'horizontal' | 'vertical';
export type OverScrollMode = 'auto' | 'always' | 'never';
export type PageScrollState = 'idle' | 'dragging' | 'settling';
+export type ScrollSensitivity = 2|3|4|5|6|7|8;
export type PagerViewOnPageScrollEvent = ReactNative.NativeSyntheticEvent<PagerViewOnPageScrollEventData>;
export interface PagerViewOnPageScrollEventData {
@@ -35,6 +36,14 @@ export interface PagerViewProps {
*/
scrollEnabled?: boolean;
+ /**
+ * Higher the `scrollSensitivity` value, more the effort to swipe.
+ * Adjust multiplier from 2-8 until you find the sweet spot.
+ *
+ * Only supported on Android.
+ */
+ scrollSensitivity?: ScrollSensitivity;
+
/**
* Executed when transitioning between pages (ether because of animation for
* the requested page change or when user is swiping/dragging between pages)
This issue body was partially generated by patch-package.
Bug
Content touches on scroll end on Android (tested on Android 5.0)
Similar issue was on on iOS when ViewPager was introduced on iOS. And you fixed that.
I have 3 pages. Every page has FlatList. Every Flat list row is TouchableOpacity. On scroll end fires onPress of TouchableOpacity.
Library version: 4.0.0 breaks it. It works on < 4.0.0