React-native-pager-view: Content touches on scroll end

Created on 29 Apr 2020  路  42Comments  路  Source: callstack/react-native-pager-view

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

bug android

Most helpful comment

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.

All 42 comments

@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

Was this page helpful?
0 / 5 - 0 ratings

Related issues

iqbalfaisal picture iqbalfaisal  路  3Comments

yashspr picture yashspr  路  5Comments

Andarius picture Andarius  路  5Comments

olhapi picture olhapi  路  4Comments

troZee picture troZee  路  8Comments