react-native-pager-view icon indicating copy to clipboard operation
react-native-pager-view copied to clipboard

Multiple WebViews in PagerView

Open velsa opened this issue 3 years ago • 15 comments
trafficstars

I am trying to display multiple webviews (with vertical scroll in them) using PagerView.

The issue that I am having is that when I scroll the web page in WebView, for some reason PagerView also handles the tap-and-drag gesture and sometimes may swipe the page. This is not the desired behavior and I am wondering how can it be avoided?

Here's the working example:

import { Dimensions, View } from 'react-native';
import PagerView from 'react-native-pager-view';
import WebView from 'react-native-webview';

const { width, height } = Dimensions.get('window');

export default function App() {  
  return (
    <View style={{ flex: 1 }}>
      <PagerView overScrollMode='never' style={{ width, height}}>
        <View style={{ flex: 1 }}>
          <WebView source={{ uri: 'https://www.lipsum.com/' }} />
        </View>
        <View style={{ flex: 1 }}>
          <WebView source={{ uri: 'https://cn.lipsum.com/' }} />
        </View>
        <View style={{ flex: 1 }}>
          <WebView source={{ uri: 'https://es.lipsum.com/' }} />
        </View>
        <View style={{ flex: 1 }}>
          <WebView source={{ uri: 'https://it.lipsum.com/' }} />
        </View>
      </PagerView>
    </View>
  );
}

https://user-images.githubusercontent.com/873278/154859909-3cfe0e92-136a-49c6-80ce-8f3ebf03dbe7.mov

Thanks for any help!

velsa avatar Feb 20 '22 19:02 velsa

We are facing the same issue. Here is a nice article explaining the source of the issue: https://bladecoder.medium.com/fixing-recyclerview-nested-scrolling-in-opposite-direction-f587be5c1a04

There is a https://github.com/callstack/react-native-pager-view/issues/164#issuecomment-965032619 which we are using, but it has some drawbacks. We are decreasing the pager swipe sensitivity, however you need to find the sweet spot between fixing this issues and making the swiping too hard.

tothvoj-gl avatar Feb 21 '22 14:02 tothvoj-gl

@velsa did you manage to work around the issue?

@tothvoj-gl didn't work for me unfortunately.

aleemb avatar Apr 16 '22 07:04 aleemb

m

jiantao88 avatar Jun 22 '22 02:06 jiantao88

having the same issue and its a great deal for my company to solve this. if you find any solution to this please share...

manosKas avatar Jun 27 '22 12:06 manosKas

I already found a solution to avoid the problem:

  • Up-Down-Left-Right gesture conflict when WebView inside PagerView

You just need to change WebView to AnAutoHeightWebView and wrap in a ScrollView, it works for my use case and probably works for yours. The fake code like this:

const sceneView = (
  <ScrollView key="1" scrollEnabled={true} showsVerticalScrollIndicator={true}>
    <AnAutoHeightWebView source={ ... } />
  </View>
)

// if react-native-pager-view
<PagerView style={styles.pagerView} initialPage={0}>
  {sceneView1}
  {sceneView2}
</PagerView>

// or if  react-native-tab-view
<TabView style={styles.tabView} 
  renderScene={({ route: { key } }) => {
    switch (key) {
       case '1': 
         return sceneView1
       case '2': 
         return sceneView2
    } 
  }}
/>

Note: you can use AnAutoHeightWebView from react-native-autoheight-webview or something wrote by yourself.

zhuanghongji avatar Jul 08 '22 03:07 zhuanghongji

@zhuanghongji yeah thats more or less what i did but i experimented a bit with pager view 6.0.0-rc2 with lazy load and i got a better result

manosKas avatar Jul 08 '22 06:07 manosKas

My solution is to customize a webview container and get touch events in the container `

public boolean dispatchTouchEvent(MotionEvent ev) {
    int x = (int) ev.getX();
    int y = (int) ev.getY();

    switch (ev.getAction()) {
        case MotionEvent.ACTION_DOWN:
            getParent().requestDisallowInterceptTouchEvent(true);
            break;
        case MotionEvent.ACTION_MOVE:
            int deltaX = Math.abs(x - mLastX);
            int deltaY = Math.abs(y - mLastY);
            if (deltaX > deltaY * 1.5) {
                getParent().requestDisallowInterceptTouchEvent(false);
            }
            break;
        default:
            break;

    }
    mLastX = x;
    mLastY = y;

    return super.dispatchTouchEvent(ev);
}

`

jiantao88 avatar Jul 19 '22 08:07 jiantao88

@jiantao88 interesting. does it work flawlessly ? did u put this code in react-native-webview dependency package or in your app's source code ?

manosKas avatar Jul 19 '22 08:07 manosKas

@manosKas I didn't use react-native-webview 。This library does not meet my needs,I am using the webview packaged by my own project

jiantao88 avatar Jul 19 '22 08:07 jiantao88

having the same issue and its a great deal for my company to solve this. if you find any solution to this please share...

hi @manosKas did you find the solution? If yes, please post it here. I have been stuck on these for days now.

Prakunj avatar Sep 21 '22 04:09 Prakunj

@Prakunj i'm using [email protected], horizontal swipe, with each page being a webview that renders a certain page. Kinda like a gmail app that views your emails. So i wrapped the webviews in scrollview. Then when webview loads, measure the height of the html page, pass height via postMessage to my component and setting the webview height with this value.

As i don't excactly know your specific case, i cant help u any further than that. if you want we can try and communicate more on chat.

manosKas avatar Sep 21 '22 07:09 manosKas

Any solution for this problem? that use react-native-webview and react-native-pager-view

TierryBr avatar Nov 22 '22 20:11 TierryBr

just dropping by to see if anyone has solved this...

manosKas avatar Jun 26 '23 12:06 manosKas

I'm having the same problem, apparently still has no solution :/

tarcisioandrade avatar Jul 11 '23 01:07 tarcisioandrade

This works... But what can i do if the webview already had scroll events (like hiding a header)

And styles that set buttons at the end of the page ??

image

I already found a solution to avoid the problem:

  • Up-Down-Left-Right gesture conflict when WebView inside PagerView

You just need to change WebView to AnAutoHeightWebView and wrap in a ScrollView, it works for my use case and probably works for yours. The fake code like this:

const sceneView = (
  <ScrollView key="1" scrollEnabled={true} showsVerticalScrollIndicator={true}>
    <AnAutoHeightWebView source={ ... } />
  </View>
)

// if react-native-pager-view
<PagerView style={styles.pagerView} initialPage={0}>
  {sceneView1}
  {sceneView2}
</PagerView>

// or if  react-native-tab-view
<TabView style={styles.tabView} 
  renderScene={({ route: { key } }) => {
    switch (key) {
       case '1': 
         return sceneView1
       case '2': 
         return sceneView2
    } 
  }}
/>

Note: you can use AnAutoHeightWebView from react-native-autoheight-webview or something wrote by yourself.

zerintia-mariob avatar Apr 18 '24 09:04 zerintia-mariob