Sincronizar las posiciones de desplazamiento ScrollView – android

Tengo 2 ScrollViews en mi disposición del androide. ¿Cómo puedo sincronizar sus posiciones de desplazamiento?

Hay un método en ScrollView …

protected void onScrollChanged(int x, int y, int oldx, int oldy) 

Desafortunadamente Google nunca pensó que necesitaríamos tener acceso a él, que es porqué lo hicieron protegido y no agregaron un gancho de "setOnScrollChangedListener". Así que tendremos que hacerlo por nosotros mismos.

Primero necesitamos una interfaz.

 package com.test; public interface ScrollViewListener { void onScrollChanged(ObservableScrollView scrollView, int x, int y, int oldx, int oldy); } 

Entonces necesitamos anular la clase ScrollView, para proporcionar el gancho ScrollViewListener.

 package com.test; import android.content.Context; import android.util.AttributeSet; import android.widget.ScrollView; public class ObservableScrollView extends ScrollView { private ScrollViewListener scrollViewListener = null; public ObservableScrollView(Context context) { super(context); } public ObservableScrollView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } public ObservableScrollView(Context context, AttributeSet attrs) { super(context, attrs); } public void setScrollViewListener(ScrollViewListener scrollViewListener) { this.scrollViewListener = scrollViewListener; } @Override protected void onScrollChanged(int x, int y, int oldx, int oldy) { super.onScrollChanged(x, y, oldx, oldy); if(scrollViewListener != null) { scrollViewListener.onScrollChanged(this, x, y, oldx, oldy); } } } 

Y debemos especificar esta nueva clase ObservableScrollView en el diseño, en lugar de las etiquetas ScrollView existentes.

 <com.test.ObservableScrollView android:id="@+id/scrollview1" ... > ... </com.test.ObservableScrollView> 

Finalmente, lo reunimos en la clase Diseño.

 package com.test; import android.app.Activity; import android.os.Bundle; public class Q3948934 extends Activity implements ScrollViewListener { private ObservableScrollView scrollView1 = null; private ObservableScrollView scrollView2 = null; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.q3948934); scrollView1 = (ObservableScrollView) findViewById(R.id.scrollview1); scrollView1.setScrollViewListener(this); scrollView2 = (ObservableScrollView) findViewById(R.id.scrollview2); scrollView2.setScrollViewListener(this); } public void onScrollChanged(ObservableScrollView scrollView, int x, int y, int oldx, int oldy) { if(scrollView == scrollView1) { scrollView2.scrollTo(x, y); } else if(scrollView == scrollView2) { scrollView1.scrollTo(x, y); } } } 

El código scrollTo () se encarga de cualquier condición de bucle para nosotros, por lo que no es necesario preocuparse por eso. La única advertencia es que esta solución no está garantizada para trabajar en versiones futuras de Android, porque estamos sobreponiendo un método protegido.

Una mejora a la solución de Andy: En su código, utiliza scrollTo, el problema es, si lanzas una vista de desplazamiento en una dirección y luego lanzas otra en otra dirección, notarás que la primera no detiene su anterior fling movimiento.

Esto se debe al hecho de que scrollView utiliza computeScroll () para hacer gestos de arrastrar, y entra en conflicto con scrollTo.

Para evitar esto, sólo tiene que programar el onScrollChanged de esta manera:

  public void onScrollChanged(ObservableScrollView scrollView, int x, int y, int oldx, int oldy) { if(interceptScroll){ interceptScroll=false; if(scrollView == scrollView1) { scrollView2.onOverScrolled(x,y,true,true); } else if(scrollView == scrollView2) { scrollView1.onOverScrolled(x,y,true,true); } interceptScroll=true; } } 

Con interceptScroll un booleano estático inicializado a true. (Esto ayuda a evitar bucles infinitos en ScrollChanged)

OnOverScrolled es la única función que encontré que se podría utilizar para detener el scrollView de arrojar (pero puede haber otros que he perdido!)

Para acceder a esta función (que está protegida) tiene que agregarla a su ObservableScrollViewer

 public void onOverScrolled(int scrollX, int scrollY, boolean clampedX, boolean clampedY) { super.onOverScrolled(scrollX, scrollY, clampedX, clampedY); } 

¿Por qué no sólo implementa OnTouchListener en su actividad. A continuación, anule el método onTouch, luego obtenga la posición de desplazamiento del primer ScrollViewOne.getScrollY() y actualice ScrollViewTwo.scrollTo(0, ScrollViewOne.getScrollY());

Sólo otra idea … 🙂

En el paquete de soporte de Android v4, Android proporciona una nueva clase llamada NestedScrollView .

Podemos reemplazar el nodo <ScrollView> por <android.support.v4.widget.NestedScrollView> en el layout xml, e implementa su NestedScrollView.OnScrollChangeListener en Java para manejar el desplazamiento.

Eso facilita las cosas.

  • El evento de desplazamiento del navegador no se dispara con suficiente frecuencia en dispositivos iOS y Android
  • Problemas de desplazamiento de GridView dentro de Viewpager dentro de NestedScrollView
  • Cómo desplazar una actividad verticalmente en Android
  • Se barajaron las imágenes al desplazar un ListView con un ViewHolder
  • Cómo habilitar el desplazamiento en un simpleadapter en el firmware X16 de Google Glass
  • Android: ¿Cómo puedo desactivar el desplazamiento de CalendarView
  • ¿Cómo hacer que el desplazamiento de Listview sea más lento?
  • Desplazamiento horizontal múltiple de RecyclerView
  • RelativeLayout - Desplazamiento hacia abajo
  • SetCurrentItem en ViewPager no se desplaza inmediatamente en la posición correcta
  • ¿Cómo trabajar, cuando listview dentro del scrollview?
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.