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.
- setLoadWithOverviewMode para XWalkView
- ¿Cómo manejar páginas web "infinitas"?
- Rendimiento de la vista web de Android a bitmap, html5 javascript, problema de devolución de llamada
- Haga que Espresso espere a que WebView termine de cargar
- WebView - no puede descargar el archivo sin solicitarlo dos veces?
¿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)?
- OnPageFinished () nunca llamado (webview)!
- Android: ¿Cómo puedo mostrar la barra de progreso al cargar datos en WebView?
- Directamente poner código html en un WebView (Android)
- ¿Cómo utilizar WebView para mostrar páginas html en modo lector de libros electrónicos?
- ¿Qué se considera onPageFinished en el WebViewClient para Android?
- La vista web de Android no reproduce video, jwembedder
- WebView causando TypeError no capturado al cargar www.google.com
- ¿Qué está causando esto en android webView?
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);