Tengo el siguiente requisito:

  • En primer lugar, los datos de la página no: 2 se recuperan del servidor & los elementos
    se rellenan en un ListView.

Teniendo en cuenta que tanto la página anterior & página siguiente están disponibles en un escenario, el siguiente código se ha añadido:

 if(prevPageNo > 0){
    mListViewActual.setOnScrollListener(this);
 }

 if(nextPageNo > 0){
    mListViewActual.setOnScrollListener(this);
 }

Qué condiciones debo poner para detectar desplácese hacia arriba & desplácese hacia abajo sobre los métodos siguientes:

  1. vacío onScroll(AbsListView vista, int firstVisibleItem, int
    visibleItemCount, int totalItemCount)
  2. vacío onScrollStateChanged(AbsListView vista, int scrollState)

Después de la acción: desplácese hacia arriba & desplácese hacia abajo se detecta , por ello, el servicio será llamado con el anterior nº de página o a la página siguiente no , para ir a buscar los elementos para ser poblada en el Listview.

Cualquier aporte será de gran ayuda.

Pasado a través de los siguientes enlaces, pero no devolver el correcto desplazamiento hacia arriba desplazamiento hacia abajo de acción:

link 1
enlace 2

InformationsquelleAutor chiranjib | 2013-05-28

16 Comentarios

  1. 88

    trate de usar el setOnScrollListener y aplicar la onScrollStateChanged con scrollState

    setOnScrollListener(new OnScrollListener(){
        public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
          //TODO Auto-generated method stub
        }
        public void onScrollStateChanged(AbsListView view, int scrollState) {
          //TODO Auto-generated method stub
          final ListView lw = getListView();
    
           if(scrollState == 0) 
          Log.i("a", "scrolling stopped...");
    
    
            if (view.getId() == lw.getId()) {
            final int currentFirstVisibleItem = lw.getFirstVisiblePosition();
             if (currentFirstVisibleItem > mLastFirstVisibleItem) {
                mIsScrollingUp = false;
                Log.i("a", "scrolling down...");
            } else if (currentFirstVisibleItem < mLastFirstVisibleItem) {
                mIsScrollingUp = true;
                Log.i("a", "scrolling up...");
            }
    
            mLastFirstVisibleItem = currentFirstVisibleItem;
        } 
        }
      });
    • Lo que si se desea determinar la dirección de desplazamiento antes de la scollState es SCROLL_STATE_IDLE? Como cuando scrollState es SCROLL_STATE_FLING o SCROLL_STATE_TOUCH_SCROLL.
    • Lo que funciona para mí es agregar este código en OnScroll no en onScrollStateChanged
    • no funcionará si todos los elementos son visibles antes de ejemplo tiene 2 artículos y desea desplazarse hacia arriba como whatsapp para cargar más
  2. 62

    Aquí es una versión modificada de algunos de los arriba indicados soluciones.

    Agregar otra clase ListView:

    package com.example.view;
    import android.content.Context;
    import android.util.AttributeSet;
    import android.view.View;
    import android.widget.AbsListView;
    public class ListView extends android.widget.ListView {
    private OnScrollListener onScrollListener;
    private OnDetectScrollListener onDetectScrollListener;
    public ListView(Context context) {
    super(context);
    onCreate(context, null, null);
    }
    public ListView(Context context, AttributeSet attrs) {
    super(context, attrs);
    onCreate(context, attrs, null);
    }
    public ListView(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
    onCreate(context, attrs, defStyle);
    }
    @SuppressWarnings("UnusedParameters")
    private void onCreate(Context context, AttributeSet attrs, Integer defStyle) {
    setListeners();
    }
    private void setListeners() {
    super.setOnScrollListener(new OnScrollListener() {
    private int oldTop;
    private int oldFirstVisibleItem;
    @Override
    public void onScrollStateChanged(AbsListView view, int scrollState) {
    if (onScrollListener != null) {
    onScrollListener.onScrollStateChanged(view, scrollState);
    }
    }
    @Override
    public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
    if (onScrollListener != null) {
    onScrollListener.onScroll(view, firstVisibleItem, visibleItemCount, totalItemCount);
    }
    if (onDetectScrollListener != null) {
    onDetectedListScroll(view, firstVisibleItem);
    }
    }
    private void onDetectedListScroll(AbsListView absListView, int firstVisibleItem) {
    View view = absListView.getChildAt(0);
    int top = (view == null) ? 0 : view.getTop();
    if (firstVisibleItem == oldFirstVisibleItem) {
    if (top > oldTop) {
    onDetectScrollListener.onUpScrolling();
    } else if (top < oldTop) {
    onDetectScrollListener.onDownScrolling();
    }
    } else {
    if (firstVisibleItem < oldFirstVisibleItem) {
    onDetectScrollListener.onUpScrolling();
    } else {
    onDetectScrollListener.onDownScrolling();
    }
    }
    oldTop = top;
    oldFirstVisibleItem = firstVisibleItem;
    }
    });
    }
    @Override
    public void setOnScrollListener(OnScrollListener onScrollListener) {
    this.onScrollListener = onScrollListener;
    }
    public void setOnDetectScrollListener(OnDetectScrollListener onDetectScrollListener) {
    this.onDetectScrollListener = onDetectScrollListener;
    }
    }

    Y una interfaz:

    public interface OnDetectScrollListener {
    void onUpScrolling();
    void onDownScrolling();
    }

    Y, finalmente, cómo utilizar:

    com.example.view.ListView listView = (com.example.view.ListView) findViewById(R.id.list);
    listView.setOnDetectScrollListener(new OnDetectScrollListener() {
    @Override
    public void onUpScrolling() {
    /* do something */
    }
    @Override
    public void onDownScrolling() {
    /* do something */
    }
    });

    En el XML de diseño:

    <com.example.view.ListView
    android:id="@+id/list"
    android:layout_width="match_parent"
    android:layout_height="match_parent"/>

    Este es mi primer tema, no me juzgues duramente. =)

    • funciona bien! gracias 🙂
    • Esto es exactamente lo que yo estaba buscando. Funciona como un encanto! +1!
    • Esto es muy preciso!! Gracias
    • Por qué no extender el desplazamiento de escucha en lugar de la vista completa? La ampliación de la vista sólo para el evento scroll, no es exactamente una buena práctica, especialmente si más adelante desea adjuntar un nuevo desplazamiento de escucha…
    • gracias a la retransmisión de trabajo
    • funciona muy bien!!! thx usted <3

  3. 44

    esta es una simple aplicación:

    lv.setOnScrollListener(new OnScrollListener() {
    private int mLastFirstVisibleItem;
    @Override
    public void onScrollStateChanged(AbsListView view, int scrollState) {
    }
    @Override
    public void onScroll(AbsListView view, int firstVisibleItem,
    int visibleItemCount, int totalItemCount) {
    if(mLastFirstVisibleItem<firstVisibleItem)
    {
    Log.i("SCROLLING DOWN","TRUE");
    }
    if(mLastFirstVisibleItem>firstVisibleItem)
    {
    Log.i("SCROLLING UP","TRUE");
    }
    mLastFirstVisibleItem=firstVisibleItem;
    }
    });

    y si usted necesita más precisión, puede utilizar esta costumbre clase ListView:

    import android.content.Context;
    import android.util.AttributeSet;
    import android.view.View;
    import android.widget.AbsListView;
    import android.widget.ListView;
    /**
    * Created by root on 26/05/15.
    */
    public class ScrollInterfacedListView extends ListView {
    private OnScrollListener onScrollListener;
    private OnDetectScrollListener onDetectScrollListener;
    public ScrollInterfacedListView(Context context) {
    super(context);
    onCreate(context, null, null);
    }
    public ScrollInterfacedListView(Context context, AttributeSet attrs) {
    super(context, attrs);
    onCreate(context, attrs, null);
    }
    public ScrollInterfacedListView(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
    onCreate(context, attrs, defStyle);
    }
    @SuppressWarnings("UnusedParameters")
    private void onCreate(Context context, AttributeSet attrs, Integer defStyle) {
    setListeners();
    }
    private void setListeners() {
    super.setOnScrollListener(new OnScrollListener() {
    private int oldTop;
    private int oldFirstVisibleItem;
    @Override
    public void onScrollStateChanged(AbsListView view, int scrollState) {
    if (onScrollListener != null) {
    onScrollListener.onScrollStateChanged(view, scrollState);
    }
    }
    @Override
    public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
    if (onScrollListener != null) {
    onScrollListener.onScroll(view, firstVisibleItem, visibleItemCount, totalItemCount);
    }
    if (onDetectScrollListener != null) {
    onDetectedListScroll(view, firstVisibleItem);
    }
    }
    private void onDetectedListScroll(AbsListView absListView, int firstVisibleItem) {
    View view = absListView.getChildAt(0);
    int top = (view == null) ? 0 : view.getTop();
    if (firstVisibleItem == oldFirstVisibleItem) {
    if (top > oldTop) {
    onDetectScrollListener.onUpScrolling();
    } else if (top < oldTop) {
    onDetectScrollListener.onDownScrolling();
    }
    } else {
    if (firstVisibleItem < oldFirstVisibleItem) {
    onDetectScrollListener.onUpScrolling();
    } else {
    onDetectScrollListener.onDownScrolling();
    }
    }
    oldTop = top;
    oldFirstVisibleItem = firstVisibleItem;
    }
    });
    }
    @Override
    public void setOnScrollListener(OnScrollListener onScrollListener) {
    this.onScrollListener = onScrollListener;
    }
    public void setOnDetectScrollListener(OnDetectScrollListener onDetectScrollListener) {
    this.onDetectScrollListener = onDetectScrollListener;
    }
    public interface OnDetectScrollListener {
    void onUpScrolling();
    void onDownScrolling();
    }
    }

    un ejemplo de uso:
    (no te olvides de añadir una Etiqueta Xml en su layout.xml)

    scrollInterfacedListView.setOnDetectScrollListener(new ScrollInterfacedListView.OnDetectScrollListener() {
    @Override
    public void onUpScrolling() {
    //Do your thing
    }
    @Override
    public void onDownScrolling() {
    //Do your thing
    }
    });
    • Básicamente no funciona para las PEQUEÑAS volutas. Este implementa un «uno a la vez» detector. Se activa sólo cuando se ha desplazado «un conjunto de células».
    • Creo que este funciona a la perfección (recordar que es la célula-sabio, no píxel-wise). He probado extensamente en comparación con la de los «cuatro pruebas» método a continuación (ejemplo Elulici la respuesta). Espero que ayude a alguien.
    • Genial y sencilla solución.
    • Genial!!! Funciona A La Perfección!
    • Solución Agradable!!!
    • La solución más sencilla y que yo tengo, Gracias
    • Por qué fab.hide() o mostrar() no está funcionando?

  4. 10
                ListView listView = getListView();
    listView.setOnScrollListener(new OnScrollListener() {
    @Override
    public void onScrollStateChanged(AbsListView view, int scrollState) {
    view.setOnTouchListener(new OnTouchListener() {
    private float mInitialX;
    private float mInitialY;
    @Override
    public boolean onTouch(View v, MotionEvent event) {
    switch (event.getAction()) {
    case MotionEvent.ACTION_DOWN:
    mInitialX = event.getX();
    mInitialY = event.getY();
    return true;
    case MotionEvent.ACTION_MOVE:
    final float x = event.getX();
    final float y = event.getY();
    final float yDiff = y - mInitialY;
    if (yDiff > 0.0) {
    Log.d(tag, "SCROLL DOWN");
    scrollDown = true;
    break;
    } else if (yDiff < 0.0) {
    Log.d(tag, "SCROLL up");
    scrollDown = true;
    break;
    }
    break;
    }
    return false;
    }
    });
    • Esta es realmente la mejor solución para esto, ya que todas las otras soluciones dependen de la corriente y el último elemento visible. Cuando dependiendo del elemento de la lista que también dependen de adaptador y si se desplaza y el adaptador no inflar siguiente punto de no saber si el usuario se desplaza hacia arriba o hacia abajo.
    • Esto es realmente una MALA solución, ya que son la configuración de la vista de toque escucha CADA vez onScrollStateChanged que tiene una gran cantidad de sobrecarga.
    • El código limpio, geniousely creativo. Gracias.
  5. 10

    Con todos los métodos publicados, hay problemas para reconocer cuando el usuario se desplaza hacia arriba desde el primer elemento o hacia abajo de la última.
    Aquí es otro enfoque para la detección de desplazamiento arriba/abajo:

            listView.setOnTouchListener(new View.OnTouchListener() {
    float height;
    @Override
    public boolean onTouch(View v, MotionEvent event) {
    int action = event.getAction();
    float height = event.getY();
    if(action == MotionEvent.ACTION_DOWN){
    this.height = height;
    }else if(action == MotionEvent.ACTION_UP){
    if(this.height < height){
    Log.v(TAG, "Scrolled up");
    }else if(this.height > height){
    Log.v(TAG, "Scrolled down");
    }
    }
    return false;
    }
    });
  6. 8

    Mi solución funciona perfectamente dar el valor exacto para cada dirección de desplazamiento.
    distanceFromFirstCellToTop contiene la distancia exacta de la primera celda a la parte superior de la Vista principal. Para guardar este valor en previousDistanceFromFirstCellToTop y como me desplazo yo lo comparo con el nuevo valor. Si es inferior, a continuación, me desplaza hacia arriba, otra cosa, me desplaza hacia abajo.

    private int previousDistanceFromFirstCellToTop;
    listview.setOnScrollListener(new OnScrollListener() {
    @Override
    public void onScrollStateChanged(AbsListView view, int scrollState) {
    }
    @Override
    public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
    View firstCell = listview.getChildAt(0);
    int distanceFromFirstCellToTop = listview.getFirstVisiblePosition() * firstCell.getHeight() - firstCell.getTop();
    if(distanceFromFirstCellToTop < previousDistanceFromFirstCellToTop)
    {
    //Scroll Up
    }
    else if(distanceFromFirstCellToTop  > previousDistanceFromFirstCellToTop)
    {
    //Scroll Down
    }
    previousDistanceFromFirstCellToTop = distanceFromFirstCellToTop;
    }
    });

    Para Xamarin de los desarrolladores, la solución es la siguiente:

    Nota: no se olvide de ejecutar en el subproceso de interfaz de usuario

    listView.Scroll += (o, e) =>
    {
    View firstCell = listView.GetChildAt(0);
    int distanceFromFirstCellToTop = listView.FirstVisiblePosition * firstCell.Height - firstCell.Top;
    if (distanceFromFirstCellToTop < previousDistanceFromFirstCellToTop)
    {
    //Scroll Up
    }
    else if (distanceFromFirstCellToTop > previousDistanceFromFirstCellToTop)
    {
    //Scroll Down
    }
    previousDistanceFromFirstCellToTop = distanceFromFirstCellToTop;
    };
    • Bonita respuesta! Yo sólo tenía que añadir un cheque si el firstCell es nulo (porque podría suceder que no se ha inflado aún).
    • Esa es la mejor y más sencilla respuesta que he encontrado acerca de la detección de dirección de desplazamiento ! Es correcto, a pesar de que el elemento de estatura pequeña o grande, funciona perfecto y estable. MUCHAS GRACIAS. Por cierto, sólo una pequeña cosa, se puede poner previousDistanceFromFirstCellToTop variable dentro del interior anónimo OnScrollListener de la clase para hacerlo mejor.
    • Gran solución! Solo falta una cosa: después de View firstCell = view.getChildAt(0); agregar : if(firstCell == null){ return; }
  7. 4

    He utilizado esta solución mucho más sencilla:

    setOnScrollListener( new OnScrollListener() 
    {
    private int mInitialScroll = 0;
    @Override
    public void onScroll(AbsListView view, int firstVisibleItem,
    int visibleItemCount, int totalItemCount) 
    {
    int scrolledOffset = computeVerticalScrollOffset();
    boolean scrollUp = scrolledOffset > mInitialScroll;
    mInitialScroll = scrolledOffset;
    }
    @Override
    public void onScrollStateChanged(AbsListView view, int scrollState) {
    }
    }
    • lo computeVerticalScrollOffset??
    • Un método protegido en el ListView
    • un millón de gracias por la pronta respuesta. Me parece que no se puede utilizar es: acabo de llegar «no se puede encontrar el símbolo…» he intentado todo punto de vista. computeVerticalScrollOffset(), myListView.computeVerticalScrollOffset() y acaba de llamada en tu código. Lo siento, soy nuevo en Android de iOS (y me encanta Android!)
    • Ya que es un método protegido, usted necesita para extrend ListView.
    • Puedo ver, gracias! Voy a ver qué puedo hacer…
  8. 4

    Para detectar el desplazamiento con mayores elementos, me prefere un onTouch Oyente:

    listview.setOnTouchListener(new View.OnTouchListener() {
    int scrollEventListSize = 5; 
    float lastY;
    //Used to correct for occasions when user scrolls down(/up) but the onTouchListener detects it incorrectly. We will store detected up-/down-scrolls with -1/1 in this list and evaluate later which occured more often
    List<Integer> downScrolledEventsHappened;
    @Override
    public boolean onTouch(View v, MotionEvent event) {
    float diff = 0;
    if(event.getAction() == event.ACTION_DOWN){
    lastY = event.getY();
    downScrolledEventsHappened = new LinkedList<Integer>();
    }
    else if(event.getAction() == event.ACTION_MOVE){
    diff = event.getY() - lastY;
    lastY = event.getY();
    if(diff>0)
    downScrolledEventsHappened.add(1);
    else 
    downScrolledEventsHappened.add(-1);
    //List needs to be filled with some events, will happen very quickly
    if(downScrolledEventsHappened.size() == scrollEventListSize+1){
    downScrolledEventsHappened.remove(0);
    int res=0;
    for(int i=0; i<downScrolledEventsHappened.size(); i++){
    res+=downScrolledEventsHappened.get(i);
    }
    if (res > 0) 
    Log.i("INFO", "Scrolled up");
    else 
    Log.i("INFO", "Scrolled down");
    }
    }
    return false; //don't interrupt the event-chain
    }
    });
  9. 3

    Tienda de la firstVisibleItem y en la siguiente onScroll comprobar si el nuevo firstVisibleItem es menor o mayor que la anterior.

    Ejemplo de pseudocódigo (no probado):

    int lastVisibleItem = 0;
    boolean isScrollingDown = false;
    void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
    if (firstVisibleItem > lastVisibleItem) {
    isScrollingDown = true;
    }
    else {
    isScrollingDown = false;
    }
    lastVisibleItem = firstVisibleItem;
    }
    • Implementado el código anterior. onScroll() se llama cuando el usuario se desplaza & llega el último elemento del ListView pero onScroll() no se llama cuando el usuario se desplaza hasta el primer elemento visible de la ScrollView. Para la primera página , primer elemento visible: 0 . Cómo manejar la situación ? onScrollStateChanged() es llamado en ambos casos.
    • Tengo un código que onScroll es llamada cada vez! Está usted seguro de que tiene el oyente y funcionando todo el tiempo? Conjunto de mListViewActual.setOnScrollListener(este), independientemente de cualquier condición!
    • He añadido mListViewActual.setOnScrollListener(este) sin ningún tipo de condición. Todavía la onScroll() no se llama cuando el usuario intenta desplazarse hacia arriba es decir, más allá de la parte superior visible elemento que es 0 en este caso.En la actualidad , como ya se mencionó , el usuario está en la página nº: 2. Sólo cuando el usuario intenta desplazarse hacia arriba , es decir, más allá de que el primer elemento visible & onScroll() es llamado , una nueva llamada de servicio pueden ser realizadas al servidor para obtener los datos de la página no: 1.
  10. 3

    Sólo desplácese escucha a tu listview.

    Si usted tiene un encabezado o pie de página debe comprobar el visible también cuentan. Si aumenta significa que el desplazamiento hacia abajo. (Inversa si hay un pie de página en lugar de la cabecera)

    Si usted no tiene ninguna encabezado o pie de página en la vista de lista puede eliminar las líneas que cheks el elemento visible de recuento.

    listView.setOnScrollListener(new AbsListView.OnScrollListener() {
    public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
    if (mLastFirstVisibleItem > firstVisibleItem) {
    Log.e(getClass().toString(), "scrolling up");
    } else if (mLastFirstVisibleItem < firstVisibleItem) {
    Log.e(getClass().toString(), "scrolling down");
    } else if (mLastVisibleItemCount < visibleItemCount) {
    Log.e(getClass().toString(), "scrolling down");
    } else if (mLastVisibleItemCount > visibleItemCount) {
    Log.e(getClass().toString(), "scrolling up");
    }
    mLastFirstVisibleItem = firstVisibleItem;
    mLastVisibleItemCount = visibleItemCount;
    }
    public void onScrollStateChanged(AbsListView listView, int scrollState) {
    }
    });

    y tener presente las variables

    int mLastFirstVisibleItem;
    int mLastVisibleItemCount;
    • Esto sólo funciona una vez que se mueva «un conjunto de células». No detectar pequeños movimientos. Funciona de forma fiable. Tenga en cuenta que se activa cuando el borde de la celda pasar el abajo de la pantalla (o adjuntando lo que sea), no de la parte superior. Tio estoy seguro de que tienes arriba y abajo transpuesto, por el camino!
    • No puedo ver ninguna diferencia en la función entre esta respuesta, y el enfoque más sencillo, por ejemplo, GaiRom arriba. He probado esquina casos, etc. ampliamente. Había una razón por la extra comparaciones, Eluleci?
  11. 1

    Por alguna razón el Android doc no cubre este, y el método utilizado no es incluso en el docs… me tomó un tiempo para encontrarlo.

    Para detectar si el desplazamiento es en la parte superior se puede usar esta.

    public boolean checkAtTop() 
    {
    if(listView.getChildCount() == 0) return true;
    return listView.getChildAt(0).getTop() == 0;
    }

    Esta forma se comprueba si la barra de desplazamiento en la parte superior. Ahora, con el fin de hacerlo por la parte inferior, usted tendría que pasar es el número de hijos que tiene, y comprobar en contra de ese número. Usted podría tener que averiguar cómo muchos están en la pantalla al mismo tiempo, y restar que a partir de su número de hijos. Nunca he tenido que hacerlo. Espero que esto ayude

  12. 1

    Esos métodos no puede ser utilizado para detectar el desplazamiento de las direcciones directamente. Hay muchas maneras de conseguir la dirección. Un código simple(no probado) para uno de esos métodos se explican a continuación :

     
    clase pública ScrollTrackingListView se extiende ListView { 
    private boolean readyForMeasurement = false; 
    private Boolean isScrollable = null; 
    privado de flotador prevDistanceToEnd = -1.0; 
    privado ScrollDirectionListener oyente = null; 
    público ScrollTrackingListView(Context context) { 
    super(context); 
    init(); 
    } 
    público ScrollTrackingListView(Contexto contexto, AttributeSet attrs) { 
    super(context, attrs); 
    init(); 
    } 
    público ScrollTrackingListView(Contexto contexto, AttributeSet attrs, int defStyle) { 
    super(context, attrs, defStyle); 
    init(); 
    } 
    private void init() { 
    ViewTreeObserver observador = getViewTreeObserver(); 
    en calidad de observador.addOnGlobalLayoutListener(globalLayoutListener); 
    setOnScrollListener(scrollListener); 
    } 
    privado ViewTreeObserver.OnGlobalLayoutListener globalLayoutListener 
    = new ViewTreeObserver.OnGlobalLayoutListener() { 
    @Override 
    public void onGlobalLayout() { 
    readyForMeasurement = true; 
    calculateDistanceToEnd(); 
    } 
    }; 
    public void registerScrollDirectionListener(ScrollDirectionListener oyente) { 
    scrollDirectionListener = oyente; 
    } 
    public void unregisterScrollDirectionListener() { 
    scrollDirectionListener = null; 
    } 
    privado OnScrollListener scrollListener 
    = new OnScrollListener() { 
    @Override 
    public void onScrollStateChanged(AbsListView absListView, int i) { 
    calculateDistanceToEnd(); 
    } 
    @Override 
    public void onScroll(AbsListView absListView, int i, int i1, int i2) { 
    //No hacer nada 
    } 
    }; 
    private void calculateDistanceToEnd() { 
    si (readyForMeasurement) { 
    //Yo estoy usando la altura de la disposición, de la barra de desplazamiento horizontal y 
    //el contenido de la desplácese hacia abajo desplazamiento 
    //computeVerticalScrollExtent se utiliza para calcular la longitud del dedo pulgar dentro de la barra de desplazamiento de la pista. 
    //La longitud del pulgar es una función de la vista de la altura y la longitud de contenido. 
    int verticalScrollExtent = computeVerticalScrollExtent(); 
    int verticalScrollOffset = computeVerticalScrollOffset(); 
    int verticalScrollRange = computeVerticalScrollRange(); 
    int horizontalScrollBarHeight = getHorizontalScrollbarHeight(); 
    /** 
    * 1. Vamos a "R" representa el rango de la barra de desplazamiento vertical. Esto corresponde a la longitud del contenido 
    * en la vista. 
    * 2. Vamos a "E" representa la medida de la barra de desplazamiento vertical. La medida es un valor constante y se 
    * (probablemente) igual a un valor proporcional a la altura de la vista. 
    * 3. Offset "o" representa la posición actual en el rango visible para el usuario. Se puede tomar 
    * los valores de "0 E". 
    * 
    * Ahora el DistanceToEnd se calcula utilizando estos tres valores de la siguiente manera : 
    * 
    * DistanceToEnd = (R - s) /E 
    * 
    * DistanceToEnd tendrá el valor en NumberOfScreenToEnd unidades. 
    * 
    */
    float distanceToEnd = 
    ((float)(verticalScrollRange - verticalScrollOffset))/((float)(verticalScrollExtent)); 
    si(prevDistanceToEnd == -1) { 
    prevDistanceToEnd = distanceToEnd; 
    } else { 
    si(oyente != null) { 
    si(distanceToEnd > prevDistanceToEnd) { 
    //El usuario se desplaza hacia arriba 
    oyente.onScrollingUp(); 
    } else { 
    //El usuario se desplaza hacia arriba 
    oyente.onScrollingDown(); 
    } 
    } 
    prevDistanceToEnd = distanceToEnd; 
    } 
    si(isScrollable == null) { 
    //Comprobar si el punto de vista de la altura es menor que una pantalla (es decir, no está activado el desplazamiento) 
    si((horizontalScrollBarHeight + verticalScrollExtent) >= verticalScrollRange) { 
    isScrollable = Booleano.FALSE; 
    } else { 
    isScrollable = Booleano.TRUE; 
    } 
    } 
    } 
    } 
    interfaz pública ScrollDirectionListener { 
    public void onScrollingUp(); 
    public void onScrollingDown(); 
    } 
    } 
    

    La idea es calcular el distanceToEnd. Si distanceToEnd aumenta, el usuario se desplaza hacia arriba y si disminuye, el usuario se desplaza hacia abajo. Que también le dará la distancia exacta hasta el final de la lista.

    Si usted está tratando de saber si el usuario se desplaza hacia arriba o hacia abajo puede reemplazar la onInterceptTouchEvent para detectar la dirección de desplazamiento, como el de abajo :

     @Override 
    public boolean onInterceptTouchEvent(MotionEvent evento) { 
    switch (event.getAction()) { 
    caso MotionEvent.ACTION_DOWN: 
    mInitialX = evento.getX(); 
    mInitialY = evento.getY(); 
    return true; 
    caso MotionEvent.ACTION_MOVE: 
    final float x = evento.getX(); 
    final float y = evento.getY(); 
    final float yDiff = y - mInitialY; //yDiff menos de 0.0 implica el desplazamiento hacia abajo mientras yDiff mayor que 0.0 implica el desplazamiento hacia arriba. Si intento añadir la menor o mayor de símbolos, la vista previa se niega a mostrarlo. 
    si(yDiff menos de 0.0) oyente.onScrollingDown(); 
    else if(yDiff mayor que 0.0) oyente.onScrollingUp(); 
    break; 
    } 
    return super.onInterceptTouchEvent(evento); 
    } 
    
  13. 1

    Truco de detectar desplácese hacia arriba o hacia abajo en la vista de lista, que acaba de llamar a esta función en onScroll función en OnScrollListener de ListView.

    private int oldFirstVisibleItem = -1;
    private protected int oldTop = -1;
    //you can change this value (pixel)
    private static final int MAX_SCROLL_DIFF = 5;
    private void calculateListScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
    if (firstVisibleItem == oldFirstVisibleItem) {
    int top = view.getChildAt(0).getTop();
    //range between new top and old top must greater than MAX_SCROLL_DIFF
    if (top > oldTop && Math.abs(top - oldTop) > MAX_SCROLL_DIFF) {
    //scroll up
    } else if (top < oldTop && Math.abs(top - oldTop) > MAX_SCROLL_DIFF) {
    //scroll down
    }
    oldTop = top;
    } else {
    View child = view.getChildAt(0);
    if (child != null) {
    oldFirstVisibleItem = firstVisibleItem;
    oldTop = child.getTop();
    }
    }
    }
  14. 1

    Forma sencilla de detectar desplácese hacia arriba/abajo en android listview

    @Override
    public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount){
    if(prevVisibleItem != firstVisibleItem){
    if(prevVisibleItem < firstVisibleItem)
    //ScrollDown
    else
    //ScrollUp
    prevVisibleItem = firstVisibleItem;
    }

    no olvides

    yourListView.setOnScrollListener(yourScrollListener);
  15. 0

    Aquí es lo que me gustaría probar primero:

    1) Crear una interfaz (vamos a llamar a OnScrollTopOrBottomListener) con estos métodos:

    vacío onScrollTop();

    vacío onScrollBottom();

    2) En la lista del adaptador, agregar a un miembro de la instancia, escrito como el interfaz creado y suministro de un setter y getter.

    3) En el getView() implementación de su adaptador, compruebe si el parámetro de posición es 0 o getCount() – 1. Comprobar también que su OnScrollTopOrBottomListener instancia no es null.

    4) Si la posición es 0, llame onScrollTopOrBottomListener.onScrollTop(). Si la posición es getCount() – 1, llamada onScrollTopOrBottomListener.onScrollBottom().

    5) En su OnScrollTopOrBottomListener aplicación, llame a los métodos apropiados para obtener los datos deseados.

    Espero que ayude de alguna manera.

    -Brandon

  16. 0

    Me he encontrado con problemas utilizando algún ejemplo en el que el tamaño de la celda de ListView es grande. Así que he encontrado una solución a mi problema que detecta el más mínimo movimiento de su dedo . He simplificado al mínimo posible y es como sigue:

    private int oldScrolly;
    @Override
    public void onScrollStateChanged(AbsListView view, int scrollState) {
    }
    @Override
    public void onScroll(AbsListView view, int firstVisibleItem, int    visibleItemCount, int totalItemCount) {
    View view = absListView.getChildAt(0);
    int scrolly = (view == null) ? 0 : -view.getTop() + absListView.getFirstVisiblePosition() * view.getHeight();
    int margin = 10;
    Log.e(TAG, "Scroll y: " + scrolly + " - Item: " + firstVisibleItem);
    if (scrolly > oldScrolly + margin) {
    Log.d(TAG, "SCROLL_UP");
    oldScrolly = scrolly;
    } else if (scrolly < oldScrolly - margin) {
    Log.d(TAG, "SCROLL_DOWN");
    oldScrolly = scrolly;
    }
    }
    });

    PD: yo uso el MARGEN para no detectar el desplazamiento hasta encontrar ese margen . Esto evita problemas cuando puedo mostrar u ocultar la vista y evitar el parpadeo de ellos.

Dejar respuesta

Please enter your comment!
Please enter your name here