SwipeRefreshLayout + WebView cuando la posición de desplazamiento está en la parte superior

Estoy intentando usar SwipeRefreshLayout con WebView.

Estoy frente al problema donde en el medio de la página, cuando el usuario se desplaza hacia abajo, no deseado refrescar patadas.

¿Cómo puedo hacer que el evento de actualización sólo ocurra cuando la posición de desplazamiento de la vista web está en la parte superior. (Es decir, está mirando la parte superior de la página)?

He logrado solucionarlo sin tener que extender nada. Echa un vistazo a este fragmento (Fragmento específico):

private ViewTreeObserver.OnScrollChangedListener mOnScrollChangedListener; @Override public void onStart() { super.onStart(); swipeLayout.getViewTreeObserver().addOnScrollChangedListener(mOnScrollChangedListener = new ViewTreeObserver.OnScrollChangedListener() { @Override public void onScrollChanged() { if (mWebView.getScrollY() == 0) swipeLayout.setEnabled(true); else swipeLayout.setEnabled(false); } }); } @Override public void onStop() { swipeLayout.getViewTreeObserver().removeOnScrollChangedListener(mOnScrollChangedListener); super.onStop(); } 

Para un contexto más amplio, echa un vistazo a mi respuesta a Android – SwipeRefreshLayout con texto vacío .

Creo que la forma recomendada de hacerlo es extender SwipeRefreshLayout y anular canChildScrollUp()https://developer.android.com/reference/android/support/v4/widget/SwipeRefreshLayout.html#canChildScrollUp ()

Así es como se hace en la aplicación Google IO 2014 Schedule: https://github.com/google/iosched/blob/master/android/src/main/java/com/google/samples/apps/iosched/ui/widget /MultiSwipeRefreshLayout.java#L76

El CustomSwipeRefreshLayout probablemente se verá así:

 public class CustomSwipeRefreshLayout extends SwipeRefreshLayout { private CanChildScrollUpCallback mCanChildScrollUpCallback; public interface CanChildScrollUpCallback { boolean canSwipeRefreshChildScrollUp(); } public void setCanChildScrollUpCallback(CanChildScrollUpCallback canChildScrollUpCallback) { mCanChildScrollUpCallback = canChildScrollUpCallback; } @Override public boolean canChildScrollUp() { if (mCanChildScrollUpCallback != null) { return mCanChildScrollUpCallback.canSwipeRefreshChildScrollUp(); } return super.canChildScrollUp(); } } 

Y en su Activity que tiene el WebView ,

 public class FooActivity implements CustomSwipeRefreshLayout.CanChildScrollUpCallback { private CustomSwipeRefreshLayout mRefreshLayout; private WebView mWebView; @Override protected void onCreate(Bundle savedInstanceState) { // after initialization mRefreshLayout.setCanChildScrollUpCallback(this); } @Override public boolean canSwipeRefreshChildScrollUp() { return mWebview.getScrollY() > 0; } } 

Simplemente implementa tu Fragment o Activity con ViewTreeObserver.OnScrollChangedListener luego establece Listener como webview.getViewTreeObserver().addOnScrollChangedListener(this);

En el método onScrollChanged() te gusta esto

  @Override public void onScrollChanged() { if (webview.getScrollY() == 0) { swipeLayout.setEnabled(true); } else { swipeLayout.setEnabled(false); } } 

Puede solucionar esto extendiendo SwipeRefreshLayout con un SwipeRefreshLayout personalizado que toma el WebView y utiliza el WebView para comprobar la posición scrollY.

Nota: Esto funcionará para desplazarse por toda la página, pero puede que no funcione con desplazamientos anidados. Además, si tiene desplazamiento horizontal, también puede agregar la lógica encontrada en esta respuesta: https://stackoverflow.com/a/24453194

 public class CustomSwipeToRefresh extends SwipeRefreshLayout { private final int yScrollBuffer = 5; private WebView mWebView; public CustomSwipeToRefresh(Context context, WebView webView) { super(context); mWebView = webView; } @Override public boolean onInterceptTouchEvent(MotionEvent event) { if (mWebView.getScrollY() > yScrollBuffer) return false; return super.onInterceptTouchEvent(event); } } 

Yo estaba enfrentando problema similar, pero ninguna de las respuestas dadas aquí funciona para mí. Así pues, conseguí una solución de esta respuesta.

Paso 1 : Crear Clase CustomWebView

 public class CustomWebView extends WebView{ private OnScrollChangedCallback mOnScrollChangedCallback; public CustomWebView(final Context context) { super(context); } public CustomWebView(final Context context, final AttributeSet attrs) { super(context, attrs); } public CustomWebView(final Context context, final AttributeSet attrs, final int defStyle) { super(context, attrs, defStyle); } @Override protected void onScrollChanged(final int l, final int t, final int oldl, final int oldt) { super.onScrollChanged(l, t, oldl, oldt); if(mOnScrollChangedCallback != null) mOnScrollChangedCallback.onScroll(l, t); } public OnScrollChangedCallback getOnScrollChangedCallback() { return mOnScrollChangedCallback; } public void setOnScrollChangedCallback(final OnScrollChangedCallback onScrollChangedCallback) { mOnScrollChangedCallback = onScrollChangedCallback; } /** * Impliment in the activity/fragment/view that you want to listen to the webview */ public static interface OnScrollChangedCallback { public void onScroll(int horizontal, int vertical); }} 

Paso 2 : En el archivo xml use la vista webview como esta:

  <com.yourpackagename.CustomWebView android:id="@+id/webview" android:layout_width="match_parent" android:layout_height="match_parent"/> 

Paso 3 : En su MainActivity use setOnScrollChangedCallback

  mWebView.setOnScrollChangedCallback(new CustomWebView.OnScrollChangedCallback(){ public void onScroll(int horizontal, int vertical){ System.out.println("=="+horizontal+"---"+vertical); //this is to check webview scroll behaviour if (vertical<50){ swipeRefreshLayout.setEnabled(true); }else{ swipeRefreshLayout.setEnabled(false); } } }); } 

La respuesta proporcionada por hiBrianLee casi funcionó para mí, pero como escribió John Shelley, getScrollY siempre devolvió 0 en mi caso (usé un ListView como el niño desplazado anidado). Sin embargo, lo que funcionó de inmediato fue utilizar canScrollVertically (que es un método View , por lo que está disponible tanto para ListView s como para WebView s, y también para cualquier otro tipo de desplazamiento de los niños).

Mi clase de diseño se ve así:

 public class NestedScrollSwipeLayout extends SwipeRefreshLayout { private ListView scrollChild; public NestedScrollSwipeLayout(Context context) { super(context); } public NestedScrollSwipeLayout(Context context, AttributeSet attrs) { super(context, attrs); } public void setScrollChild(ListView child) { this.scrollChild = child; } @Override public boolean canChildScrollUp() { return (scrollChild != null && scrollChild.canScrollVertically(-1)) || super.canChildScrollUp(); } } 

(Como se mencionó, canScrollVertically es un método View , por lo que el ListView puede ser reemplazado con seguridad por una View general o cualquier otra clase de vista especializada).

I encontrar una solución para ello. Sólo usa el CoordinatorLayout como el diseño raíz y añade layout_behavior = "@ string / appbar_scrolling_view_behavior" a tu SwipeRefreshLayout.It es perfecto para mí.

Use SwipeRefreshLayout normalmente como lo hace con otras vistas, pero habilita el desplazamiento anidado.

 swipeRefreshLayout.setNestedScrollingEnabled(true); 
  • Android WebView con caracteres UTF-8 ilegibles.
  • Superposición azul de OnClick
  • Android Wikipedia La búsqueda de artículos no aparece correctamente en mi webview?
  • Botón de retroceso y avance para webview en android. ¿cómo?
  • React-nativo de Android WebView manejar clic en Url antes de cargar
  • Android webview + javascript no mostrar la salida en android 4.0.x, 3.x
  • ¿Los navegadores webview de android admiten funciones html5?
  • Capas dentro de un HTML dentro de una webview
  • ¿Tiene el nuevo Android WebView el mismo rendimiento que CrossWalk WebView?
  • WebSocket en Android WebView
  • ¿Qué hace stopLoading () realmente hacer?
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.