2014-01-25 47 views

回答

0

嘗試使用setOnScrollListener並實現onScrollStateChanged。滾動狀態可以是空閒,觸摸滾動或一甩

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 
     if(scrollState == 2) Log.i("a", "fast scroll"); 
    } 
    }); 
} 
+0

這並不意味着它的快速壽。即使用戶以很小的加速度閃爍,這也會觸發滾動。 –

+0

你想確定它滾動的速度有多快? –

+0

我試過已經和滾動觸摸屏幕或滾動fastScroller返回相同的scrollState。我正在使用帶有SLIDE_IN效果的JazzyListView,並且在ListView中啓用了快速滾動功能。當我快速滾動時,它不能正常工作,因爲第一個或最後一個可見項目多次不可見。我想在進入快速滾動模式時禁用該效果,並在離開時重新啓用它。 – mollymay

6

反射允許你這樣做。通過查看AbsListView source code,有一個FastScroller對象,它表示圍繞快速滾動功能的包裝。 Its source code顯示了一個有趣的field

/** 
* Current decoration state, one of: 
* <ul> 
* <li>{@link #STATE_NONE}, nothing visible 
* <li>{@link #STATE_VISIBLE}, showing track and thumb 
* <li>{@link #STATE_DRAGGING}, visible and showing preview 
* </ul> 
*/ 
private int mState; 

該字段包含FastScroller對象的狀態。解決方案包括通過反射讀取該字段的值,每次觸發onScroll()onScrollStateChanged()方法。

此代碼實現上述解決方案:

private class CustomScrollListener implements OnScrollListener { 

    private ListView list; 
    private int mState = -1; 
    private Field stateField = null; 
    private Object mFastScroller; 
    private int STATE_DRAGGING; 

    public CustomScrollListener() { 
     super(); 

     String fastScrollFieldName = "mFastScroller"; 
     // this has changed on Lollipop 
     if (Build.VERSION.SDK_INT >= 21) { 
      fastScrollFieldName = "mFastScroll"; 
     } 

     try { 
      Field fastScrollerField = AbsListView.class.getDeclaredField(fastScrollFieldName); 
      fastScrollerField.setAccessible(true); 
      mFastScroller = fastScrollerField.get(list); 

      Field stateDraggingField = mFastScroller.getClass().getDeclaredField("STATE_DRAGGING"); 
      stateDraggingField.setAccessible(true); 
      STATE_DRAGGING = stateDraggingField.getInt(mFastScroller); 

      stateField = mFastScroller.getClass().getDeclaredField("mState"); 
      stateField.setAccessible(true); 
      mState = stateField.getInt(mFastScroller); 

     } catch (NoSuchFieldException e) { 
      e.printStackTrace(); 
     } catch (IllegalAccessException e) { 
      e.printStackTrace(); 
     } 
    } 

    @Override 
    public void onScrollStateChanged(AbsListView view, int scrollState) { 

     // update fast scroll state 
     try { 
      if (stateField != null) { 
       mState = stateField.getInt(mFastScroller); 
      } 
     } catch (IllegalAccessException e) { 
      e.printStackTrace(); 
     } 


     if (mState == STATE_DRAGGING)) { 
      // the user is fast scrolling through the list 
     } 
    } 

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

     // update fast scroll state 
     try { 
      if (stateField != null) { 
       mState = stateField.getInt(mFastScroller); 
      } 
     } catch (IllegalAccessException e) { 
      e.printStackTrace(); 
     } 

    } 
} 
+0

fastScrollerField.get(grid)中的字段「grid」是什麼?使用它也有任何缺點,我假設反射使這'緩慢' – toidiu

+0

'grid'是我使用的GridView。我正在將其更改爲「清單」,以便更清楚。 – Sebastiano

+0

另外假設如果源從sdk更改爲sdk,這可能會中斷?並因此嘗試捕捉。看起來像一個hacky解決方案 – toidiu