2011-11-15 7 views
9

Me está saliendo un pequeño problema. Lo que estoy haciendo: tengo un ListView que tiene algunas imágenes. Para que el desplazamiento sea más suave, desactivé las imágenes para que se muestren al desplazarse. Ahora parece haber un bug en Android que a veces hace que el estado de desplazamiento no cambie de SCROLL_STATE_FLING a SCROLL_STATE_IDLE, lo que hace que mis imágenes no vuelvan a aparecer.Android: onScrollStateChanged SCROLL_STATE_IDLE a veces no enciende

Mi primer pensamiento fue configurar un onTouchListener y comprobar cuando recibo ACTION_UP, pero eso no ayuda porque el estado SCROLL_STATE_FLING obviamente se está configurando después de eso. Así que ahora he pensado que podría iniciar un temporizador cuando se establezca el estado SCROLL_STATE_FLING y verificar después de un tiempo si el estado todavía está en modo fling y luego invalidar mi vista. Pero no creo que sea una muy buena solución.

¿Alguien tiene una mejor idea de cómo podría hacer eso? He visto this respuesta pero necesito una solución para el nivel de API < 9 (además de que también sucede a veces cuando no está overscrolling)

Aquí está mi código para que:

mList.setOnScrollListener(new OnScrollListener() { 

     @Override 
     public void onScrollStateChanged(AbsListView view, int scrollState) { 
      mListAdapter.setIsScrolling(scrollState != SCROLL_STATE_IDLE); 
      Log.i(this, "scrollStateChanged" + scrollState); 
      if (scrollState == SCROLL_STATE_IDLE) { 
       mList.invalidateViews(); 
      } 
     } 

     @Override 
     public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { 
     } 
    }); 

Gracias, María

Respuesta

17

que tenía el mismo problema, por lo que mi solución fue detectar simplemente si la posición ScrollView ha llegado a la última página y en ese caso siempre cargar las imágenes sin tener en cuenta del estado de desplazamiento (ya que el problema parece ocurrir siempre cuando el usuario se lanza al final de la vista de lista). Por lo tanto la modificación de su código que tendría:

mList.setOnScrollListener(new OnScrollListener() { 

    @Override 
    public void onScrollStateChanged(AbsListView view, int scrollState) { 
     mListAdapter.setIsScrolling(scrollState != SCROLL_STATE_IDLE); 
     Log.i(this, "scrollStateChanged" + scrollState); 

     int first = view.getFirstVisiblePosition(); 
     int count = view.getChildCount(); 

     if (scrollState == SCROLL_STATE_IDLE || (first + count > mListAdapter.getCount())) { 
      mList.invalidateViews(); 
     } 
    } 

    @Override 
    public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { 
    } 
}); 
+0

simple, pero no pensé en eso, ¡gracias! –

+1

De nada. Descubrí que es cuando tocas un extremo de la vista de lista mientras tu dedo aún toca la pantalla. Así que esto podría suceder en la parte superior de la lista también. El código que tengo se puede modificar para que siempre cargue también la primera página. –

+0

sí, también estaba sucediendo en la parte superior, pero eso es un cambio fácil. –

1

he tenido este mismo problema y una solución publicado en el bug list:

Para cualquiera aún en marcha en thi s problema (como lo fue la semana pasada) una solución que funciona para mí es la siguiente: Si SDKInt androide == 7 estableció un onTouchListener en el (Abs)ListView

En ese onTouchListener cuando la acción OnTouch evento es MotionEvent.ACTION_UP || action == MotionEvent.ACTION_CANCEL que la fuerza un onScrollStateChanged con una primera SCROLL_STATE_FLING y luego un ejemplo SCROLL_STATE_IDLE

Código: En el onCreate:

if(androidSDKInt <= 7){ 
     listViewDateSelector.setOnTouchListener(new FingerTracker(onScrollListener));  } 

A continuación, añadir una clase privada con:

private class FingerTracker implements View.OnTouchListener { 
     private OnScrollListener myOnScrollListener; 

     public FingerTracker(OnScrollListener onScrollListener){ 
      myOnScrollListener = onScrollListener;   } 

     public boolean onTouch(View view, MotionEvent event) { 
      final int action = event.getAction(); 
      boolean mFingerUp = action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_CANCEL; 
      if (mFingerUp) { 
       myOnScrollListener.onScrollStateChanged((AbsListView) view, OnScrollListener.SCROLL_STATE_FLING); 
       myOnScrollListener.onScrollStateChanged((AbsListView) view, OnScrollListener.SCROLL_STATE_IDLE); 
      } 
      return false;   }  } 
+1

Pero eso haría que el estado de reposo que se fijará cuando todavía podría estar arrojando, correcto? –

+0

Es cierto. No había pensado en eso. Llamará al método inactivo también mientras arroja ... Esto no es un problema para mi implementación ya que la arrojadiza aún continuará, y cuando eso termine automáticamente restablecerá el estado inactivo, pero puedo imaginar que esto podría no funcionar para todos. – Kasium

Cuestiones relacionadas