2012-03-09 18 views
7

C'è un modo per identificare se listview sta scorrendo verso l'alto o verso il basso?Come rilevare se un listview sta scorrendo verso l'alto o verso il basso in Android?

OnScrollListener non mi aiuta in questo caso.

Grazie in anticipo!

+0

esattamente quello che vuoi? Puoi spiegare di più ... –

+0

Voglio fare un po 'di codice quando l'elenco sta scorrendo verso l'alto, e fare altro codice quando l'elenco sta scorrendo verso il basso. quindi, voglio rilevare se sta scorrendo verso l'alto o verso il basso – dor506

+3

Vedi questo http://stackoverflow.com/questions/6358428/implementation-of-onscrolllistener-to-detect-the-end-of-scrolling-in-a-listview –

risposta

12

questa è una semplice implementazione:

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; 

     } 
    }); 
+2

Utile solo quando l'elemento in cima non è più il primo elemento.Non ti dirò la direzione se scorri avanti e indietro mentre lo stesso oggetto rimane in alto. – AndroidDev

4

C'è un metodo in ScrollViews che riporta lo spostamento di pergamene. Si chiama onScrollChanged(). Tuttavia, è dichiarato protetto, quindi è necessario creare una classe wrapper per ottenere l'accesso. Per l'utilizzo del metodo, controlla i documenti di Android.

In primo luogo, creare un'interfaccia per esporre il metodo protetto

public interface OnScrollListener { 
void onScrollChanged(int x, int y, int oldx, int oldy); 
} 

Quindi, crea il tuo involucro ed estendere ScrollView

public class ReportingScrollView extends ScrollView { 
private OnScrollListener onScrollListener = null; 

public ReportingScrollView(Context context) { 
    super(context); 
} 

public ReportingScrollView(Context context, AttributeSet attrs, int defStyle) { 
    super(context, attrs, defStyle); 
} 

public ReportingScrollView(Context context, AttributeSet attrs) { 
    super(context, attrs); 
} 

public void setOnScrollListener(OnScrollListener onScrollListener) { 
    this.onScrollListener = onScrollListener; 
} 

@Override 
protected void onScrollChanged(int x, int y, int oldx, int oldy) { 
    super.onScrollChanged(x, y, oldx, oldy); 
    if (onScrollListener != null) { 
     onScrollListener.onScrollChanged(x, y, oldx, oldy); 
    } 
} 
} 

Infine, includere nel vostro layout di XML come una visualizzazione personalizzata, e attacca gli ascoltatori come al solito.

<your.package.ReportingScrollView /> 

scrollingandtrolling.setOnScrollListener(new OnScrollListener() {...}); 
+2

Questo sembra essere chiamato solo quando si lancia l'elenco, non viene ripetutamente chiamato. –

0

La soluzione data da alcuni Noob Student è buono: è necessario creare un wrapper di utilizzare l'onScrollChanged protetta (int x, int y, int oldx , int oldy), che viene attivato più spesso dello standard AbsListView.OnScrollListener.onScrollStateChanged (vista AbsListView, int scrollState).

Sfortunatamente onScrollChanged() restituisce sempre 0 come parametri, indipendentemente dal modo in cui si scorre, e sembra rilevare solo quando termina lo scorrimento, raggiungendo la parte superiore o inferiore dell'elenco.

Quindi ho utilizzato il seguente codice per rilevare la direzione corretta dello scorrimento: utilizza il getTop() del primo elemento visibile ma utilizza anche la sua posizione per capire quando il primo elemento non è più visibile; durante questa transizione dell'oggetto, la direzione di scorrimento è data dalla posizione dell'oggetto stesso.

 @Override 
     public void onScrollChanged(int x, int y, int oldx, int oldy) { 

      if(listView.getChildAt(0) != null) { 
       int scrollingDir = NO_SCROLLING; 
       int firstChildTop = listView.getChildAt(0).getTop(); 

       if (listView.getFirstVisiblePosition() == mLastFirstVisiblePosition) { 
        if (mLastFirstChildTop < firstChildTop) { 
         //Scrolling DOWN 
         scrollingDir = SCROLLING_DOWN; 
        } else if (mLastFirstChildTop > firstChildTop) { 
         //Scrolling UP 
         scrollingDir = SCROLLING_UP; 
        } 
       } else if(listView.getFirstVisiblePosition() > mLastFirstVisiblePosition) { 
        //Scrolling UP 
        scrollingDir = SCROLLING_UP; 
       } else { 
        //Scrolling DOWN 
        scrollingDir = SCROLLING_DOWN; 
       } 
       mLastFirstVisiblePosition = listView.getFirstVisiblePosition(); 
       mLastFirstChildTop = firstChildTop; 

       switch(scrollingDir) { 
        case SCROLLING_DOWN: 
         //Your DOWN scrolling code here 
         break; 

        case SCROLLING_UP: 
         //Your UP scrolling code here 
         break; 

        default: 
        case NO_SCROLLING: 
         break; 
       } 
      } 
     } 
0
list.setOnScrollListener(new OnScrollListener() { 
     int last_item; 
     @Override 
     public void onScrollStateChanged(AbsListView view, int scrollState) { 

     } 

     @Override 
     public void onScroll(AbsListView view, int firstVisibleItem, 
       int visibleItemCount, int totalItemCount) { 
      if(last_item<firstVisibleItem+visibleItemCount-1){ 
       System.out.println("List is scrolling upwards"); 
      } 
      else if(last_item>firstVisibleItem+visibleItemCount-1){ 
       System.out.println("List is scrolling downwards"); 
      } 
      last_item = firstVisibleItem+visibleItemCount-1; 
     } 
    }); 

Qui basato sull'ultimo elemento visibile a decidere se la lista sta andando verso l'alto o verso il basso

1

Una soluzione semplice e di lavoro.

private int lastPosition = -1; 

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

      if(firstVisibleItem > lastPosition) 
      { 
       Logger.print("Going Down"); 
      } 
      else 
      { 
       Logger.print("Going Up"); 
      } 

      lastPosition = firstVisibleItem; 
     } 
+1

ha funzionato perfettamente, grazie! – error1337

1

per il quale mai ancora alla ricerca di una risposta per Kotlin, questo funziona per lo

MainListView.setOnScrollListener(object :AbsListView.OnScrollListener { 
    // var VisibleItem: Int = 0 
     override fun onScroll(p0: AbsListView?, FirstVisibleItem: Int, i2: Int, i3: Int) { 
     /* 
     if(VisibleItem < FirstVisibleItem) 
     { 
     Toast.makeText(applicationContext,"Scrolling Down",Toast.LENGTH_SHORT).show() 
      fab.hide() 
     } 
     if(VisibleItem >FirstVisibleItem) 
     { 
      fab.show() 
      Toast.makeText(applicationContext,"Scrolling Up",Toast.LENGTH_SHORT).show() 
     } 
      VisibleItem=FirstVisibleItem; 
    */ 
     } 
     override fun onScrollStateChanged(p0: AbsListView?, p1: Int) { 
      if (p1 == 1) { 
       fab.hide() 
      } else { 
       fab.show() 
      } 
     } 

    }) 
} 

Scommentare di utilizzare un metodo alternativo.

Problemi correlati