react / react/react-native

ScrollView bounces back on some android devices, when ScrollVIew set horizontal is true。

Abierto
#38,236 7 comentarios 4 reacciones 0 asignados Ver en GitHub

Nadie ha tomado este issue todavía.

Component: ScrollView Issue: Author Provided Repro Needs: Repro Newer Patch Available Platform: Android
Lenguaje dominante
C++
Estrellas
127k
Forks
25.3k
Merge medio
1 d 23 h
PR fusionados (30 d)
4

Descripción

Description

Vertical scrolling, Android has made special adjustments to the P version, but horizontal scrolling has not been addressed, resulting in rebound issues when horizontal scrolling is too fast. The following is the processing code for vertical scrolling and the code for not processing the Android P version during horizontal scrolling.

vertical scrollview

@Override
  public void fling(int velocityY) {
    final int correctedVelocityY = correctFlingVelocityY(velocityY);

    if (mPagingEnabled) {
      flingAndSnap(correctedVelocityY);
    } else if (mScroller != null) {
      // FB SCROLLVIEW CHANGE

      // We provide our own version of fling that uses a different call to the standard OverScroller
      // which takes into account the possibility of adding new content while the ScrollView is
      // animating. Because we give essentially no max Y for the fling, the fling will continue as
      // long
      // as there is content. See #onOverScrolled() to see the second part of this change which
      // properly
      // aborts the scroller animation when we get to the bottom of the ScrollView content.

      int scrollWindowHeight = getHeight() - getPaddingBottom() - getPaddingTop();

      mScroller.fling(
          getScrollX(), // startX
          getScrollY(), // startY
          0, // velocityX
          correctedVelocityY, // velocityY
          0, // minX
          0, // maxX
          0, // minY
          Integer.MAX_VALUE, // maxY
          0, // overX
          scrollWindowHeight / 2 // overY
          );

      ViewCompat.postInvalidateOnAnimation(this);

      // END FB SCROLLVIEW CHANGE
    } else {
      super.fling(correctedVelocityY);
    }
    handlePostTouchScrolling(0, correctedVelocityY);
  }

  private int correctFlingVelocityY(int velocityY) {
    if (Build.VERSION.SDK_INT != Build.VERSION_CODES.P) {
      return velocityY;
    }

    // Workaround.
    // On Android P if a ScrollView is inverted, we will get a wrong sign for
    // velocityY (see https://issuetracker.google.com/issues/112385925).
    // At the same time, mOnScrollDispatchHelper tracks the correct velocity direction.
    //
    // Hence, we can use the absolute value from whatever the OS gives
    // us and use the sign of what mOnScrollDispatchHelper has tracked.
    float signum = Math.signum(mOnScrollDispatchHelper.getYFlingVelocity());
    if (signum == 0) {
      signum = Math.signum(velocityY);
    }
    return (int) (Math.abs(velocityY) * signum);
  } 

horizontal scrollview

  @Override
  public void fling(int velocityX) {
    if (DEBUG_MODE) {
      FLog.i(TAG, "fling[%d] velocityX %d", getId(), velocityX);
    }

    // Workaround.
    // On Android P if a ScrollView is inverted, we will get a wrong sign for
    // velocityX (see https://issuetracker.google.com/issues/112385925).
    // At the same time, mOnScrollDispatchHelper tracks the correct velocity direction.
    //
    // Hence, we can use the absolute value from whatever the OS gives
    // us and use the sign of what mOnScrollDispatchHelper has tracked.
    final int correctedVelocityX =
        (int) (Math.abs(velocityX) * Math.signum(mOnScrollDispatchHelper.getXFlingVelocity()));

    if (mPagingEnabled) {
      flingAndSnap(correctedVelocityX);
    } else if (mScroller != null) {
      // FB SCROLLVIEW CHANGE

      // We provide our own version of fling that uses a different call to the standard OverScroller
      // which takes into account the possibility of adding new content while the ScrollView is
      // animating. Because we give essentially no max X for the fling, the fling will continue as
      // long
      // as there is content. See #onOverScrolled() to see the second part of this change which
      // properly
      // aborts the scroller animation when we get to the bottom of the ScrollView content.

      int scrollWindowWidth =
          getWidth() - ViewCompat.getPaddingStart(this) - ViewCompat.getPaddingEnd(this);

      mScroller.fling(
          getScrollX(), // startX
          getScrollY(), // startY
          correctedVelocityX, // velocityX
          0, // velocityY
          0, // minX
          Integer.MAX_VALUE, // maxX
          0, // minY
          0, // maxY
          scrollWindowWidth / 2, // overX
          0 // overY
          );

      ViewCompat.postInvalidateOnAnimation(this);

      // END FB SCROLLVIEW CHANGE
    } else {
      super.fling(correctedVelocityX);
    }
    handlePostTouchScrolling(correctedVelocityX, 0);
  }
React Native Version

0.71.4

Output of npx react-native info

System:
OS: macOS 13.2
CPU: (12) x64 Intel(R) Core(TM) i7-8750H CPU @ 2.20GHz
Memory: 19.23 MB / 16.00 GB
Shell: 5.8.1 - /bin/zsh
Binaries:
Node: 16.14.0 - /usr/local/bin/node
Yarn: 1.22.10 - /usr/local/bin/yarn
npm: 8.3.1 - /usr/local/bin/npm
Watchman: Not Found
Managers:
CocoaPods: 1.10.1 - /usr/local/bin/pod
SDKs:
iOS SDK:
Platforms: DriverKit 22.2, iOS 16.2, macOS 13.1, tvOS 16.1, watchOS 9.1
Android SDK: Not Found
IDEs:
Android Studio: 2022.1 AI-221.6008.13.2211.9514443
Xcode: 14.2/14C18 - /usr/bin/xcodebuild
Languages:
Java: 19.0.1 - /usr/bin/javac
npmPackages:
@react-native-community/cli: Not Found
react: 18.2.0 => 18.2.0
react-native: 0.71.4 => 0.71.4
react-native-macos: Not Found
npmGlobalPackages:
react-native: Not Found

Steps to reproduce

Set scrollview to horizontal scrolling, then fill in sub elements to allow scrollview to scroll horizontally, and then continuously slide towards the bottom when scrollview scrolls to the bottom, causing scrollview to experience rebound issues.

Snack, code example, screenshot, or link to a repository

1688726913088

Guía de contribución

Abrir la guía de contribución

Primeros pasos

  1. Lee el issue completo y luego la guía de contribución del proyecto.
  2. Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
  3. Haz un fork del repositorio y trabaja en una rama.
  4. Abre un pull request que haga referencia al número del issue.

Línea de trabajo

Revisa la ruta de Android ScrollView fling(int velocityX) mostrada en el issue y compárala con la implementación vertical de fling y la solución alternativa de Android P. Reproduce el deslizamiento horizontal rápido al final del contenido desplazable en un dispositivo Android afectado; se considera terminado cuando ScrollView ya no rebota y el comportamiento normal del fling horizontal sigue intacto.

Escrito por el modelo de indexación a partir del texto del issue.

Evaluación

Stack tecnológico
android, java, react-native
Área
mobile
Tipo de issue
Error
Dificultad
3/5
Tiempo estimado
1-2 días
Estado de actividad
Estancado
Claridad
Bastante claro
Aptitud para principiantes
38/100

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.