Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[table] Android scroll conflict #9

Closed
Runtime007 opened this issue Jan 14, 2020 · 8 comments
Closed

[table] Android scroll conflict #9

Runtime007 opened this issue Jan 14, 2020 · 8 comments

Comments

@Runtime007
Copy link

In Android, if Html in ScrollView and table's columns > 2, it's not easy to scroll table to the left to show other columns. iOS is OK.

<ScrollView>
    <HTML
         {...htmlConfig}
         html={html}
    />
</ScorllView>

image

@jsamr
Copy link
Collaborator

jsamr commented Jan 14, 2020

@Runtime007 To help you, I will need you to produce a minimal reproducible example, in the form of an expo snack or git repository. Also, I am not sure about the issue!

@Runtime007
Copy link
Author

Runtime007 commented Jan 15, 2020

here is the code. Android 9.0 Galaxy s9+. I try to scroll the table to left or right, but the ScrollView captured the move event and it scrolls down or up, there is no response for the table sometimes. @jsamr

@Runtime007
Copy link
Author

Runtime007 commented Jan 16, 2020

hi, @jsamr, this issue has troubled me several days. I try to fix it by setting PanResponder for webview and listening to touch events to avoid scroll conflict but come to nothing. So I have to change android source code for react-native-webview, and it works.

protected static class RNCWebView extends WebView implements LifecycleEventListener {
    ...

    float startX = 0;
    float startY = 0;
    float dx = 0;
    float dy = 0;

    @Override
    public boolean onTouchEvent(MotionEvent event){
      switch (event.getAction()) {
        case MotionEvent.ACTION_DOWN:
          getParent().requestDisallowInterceptTouchEvent(true);
          startX = event.getX();
          startY = event.getY();
          break;
        case MotionEvent.ACTION_MOVE:
          dx = Math.abs(event.getX() - startX);
          dy = Math.abs(event.getY() - startY);
          if (dx > dy) {
            getParent().requestDisallowInterceptTouchEvent(true);
          } else {
            getParent().requestDisallowInterceptTouchEvent(false);
          }
          break;
      }

      return super.onTouchEvent(event);
    }
    ...

}

@jsamr
Copy link
Collaborator

jsamr commented Jan 16, 2020

@Runtime007 I'll take a look today!

@jsamr
Copy link
Collaborator

jsamr commented Jan 16, 2020

@Runtime007 The issue is that you would like a minimum dy value for the gesture to trigger a scroll event in the root ScrollView component. Something like the activeOffsetY prop from RNGH PanGestureHandler

I see two options :

  1. Get inspiration from this hacking.
  2. Render table previews and offer full table layout in a separate modal or screen after user interaction.

In either cases, you will need makeCustomTableRenderer.

I hope you'll find something workable. I will close because this limitation is broadly from react-native. But if you dig any workaround, please post your findings!

Best,

JSR

@jsamr jsamr closed this as completed Jan 16, 2020
@jsamr jsamr pinned this issue Jan 16, 2020
@jsamr
Copy link
Collaborator

jsamr commented Jan 16, 2020

hi, @jsamr, this issue has troubled me several days. I try to fix it by setting PanResponder for webview and listening to touch events to avoid scroll conflict but come to nothing. So I have to change android source code for react-native-webview, and it works.

protected static class RNCWebView extends WebView implements LifecycleEventListener {
    ...

    float startX = 0;
    float startY = 0;
    float dx = 0;
    float dy = 0;

    @Override
    public boolean onTouchEvent(MotionEvent event){
      switch (event.getAction()) {
        case MotionEvent.ACTION_DOWN:
          getParent().requestDisallowInterceptTouchEvent(true);
          startX = event.getX();
          startY = event.getY();
          break;
        case MotionEvent.ACTION_MOVE:
          dx = Math.abs(event.getX() - startX);
          dy = Math.abs(event.getY() - startY);
          if (dx > dy) {
            getParent().requestDisallowInterceptTouchEvent(true);
          } else {
            getParent().requestDisallowInterceptTouchEvent(false);
          }
          break;
      }

      return super.onTouchEvent(event);
    }
    ...

}

Third option : I would suggest you offer a PR to react-native-webview with a prop enabling the behavior you have implemented. Not sure about the best chose of words though!

@Runtime007
Copy link
Author

@Runtime007 The issue is that you would like a minimum dy value for the gesture to trigger a scroll event in the root ScrollView component. Something like the activeOffsetY prop from RNGH PanGestureHandler

I see two options :

  1. Get inspiration from this hacking.
  2. Render table previews and offer full table layout in a separate modal or screen after user interaction.

In either cases, you will need makeCustomTableRenderer.

I hope you'll find something workable. I will close because this limitation is broadly from react-native. But if you dig any workaround, please post your findings!

Best,

JSR

Thank you very much for your proposals, I'll check and try, to see if it can be implemented on the react side.

Best regards.

@chr314
Copy link
Contributor

chr314 commented May 16, 2020

#14 merged, now you can use onMessage and injectedJavaScript webview props

you can disable scroll of ScrollView with scrollEnabled prop

<ScrollView scrollEnabled={this.state.scrollEnabled}>
          <HTML
            alterNode={alterNode}
            renderers={this.htmlRenderers}
            ignoredTags={IGNORED_TAGS}
            html={this.state.content}
          />
</ScrollView>
  scrollTimer;
  onTableMessage = (event) => {
    if (event.data === 'scroll') {
      if (this.scrollTimer) {
        clearTimeout(this.scrollTimer);
      }
      this.setState({scrollEnabled: false}, () => {
        this.scrollTimer = setTimeout(() => {
          this.setState({scrollEnabled: true});
        }, 100);
      });
    }
  };

  htmlRenderers = {
    table: makeTableRenderer({
      WebViewComponent: WebView,
      webViewProps: {
        onMessage: this.onTableMessage,
        injectedJavaScript:
          "setTimeout(() => {document.addEventListener('scroll', function () {window.ReactNativeWebView.postMessage('scroll');},true);}, 300);",
      },
    }),
  };

@jsamr jsamr changed the title Android scroll conflict [table-plugin] Android scroll conflict Nov 26, 2020
@jsamr jsamr changed the title [table-plugin] Android scroll conflict [table] Android scroll conflict Mar 26, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants