2011-09-06 23 views

回答

36

編輯

見下面的評論,爲什麼,尤其是在不同版本的API(ESP後來者),這不是一個簡單的方法,如果你是列表的頂部(填充等)。但是,它確實爲您提供API 14以下設備解決方案的開始:就我多年前的實施而言 - 當時的工作非常完美。

+0

很好...乾淨,簡單 – Houston

+5

這並不總是返回0當我在列表的頂部 – JackMahoney

+0

(您可以添加... getTop ()> 0 || ... getTop() Graeme

1

您可以使用OnScrollListener來通知位置0現在可見。使用onScroll方法。

+5

我的列表項是非常大的,所以我不能比較一下,看是否firstVisibleItem爲0,因爲該項目覆蓋了屏幕的一半。如果該項目只有一半可見(在頂部)。那麼firstVisibleItem也是0,它不是listView的最頂層。 – ShineDown

+3

提問者想知道最頂點的時候,而不是當達到頂級項目時。這仍然會觸發,如果在第一項上,但不是在最頂點 – wi1

-1
lstView.setOnScrollListener(new AbsListView.OnScrollListener() { 

      @Override 
      public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { 
       //To change body of implemented methods use File | Settings | File Templates. 
       if (0 == firstVisibleItem){ 
        Toast.makeText(MyActivity.this, "Scroll to Top ", Toast.LENGTH_SHORT).show(); 
       } 
      } 
     }); 
+5

提問者希望瞭解最頂點的時候,而不是當達到頂級項目時。如果在第一個項目上,但是不在最高點,這仍會觸發。 – wi1

2

你將需要檢查的是第一個可見的位置,然後將格雷姆的解決方案,看是否第一個可見的ListView項是在頂部位置。

喜歡的東西 lv.getFirstVisiblePosition()== 0 & &(lv.getChildCount()== 0 || lv.getChildAt(0).getTop()== 0)

21

我知道這個問題是舊的,但它顯示在谷歌搜索結果的頂部。有一個在API級別14引入了新的方法,讓我們需要什麼:

http://developer.android.com/reference/android/view/View.html#canScrollVertically%28int%29

對於舊平臺可以使用在V4支持庫的ViewCompat類似的靜態方法。請參閱下面的編輯。

與Graeme的方法不同,此方法不受由內部視圖重用ListView和/或標頭偏移引起的問題的影響。

編輯:最終的解決方案

我發現在SwipeRefreshLayout的源代碼處理這個方法。它可以被重寫爲:

public boolean canScrollUp(View view) { 
    if (android.os.Build.VERSION.SDK_INT < 14) { 
    if (view instanceof AbsListView) { 
     final AbsListView absListView = (AbsListView) view; 
     return absListView.getChildCount() > 0 
      && (absListView.getFirstVisiblePosition() > 0 || absListView 
       .getChildAt(0).getTop() < absListView.getPaddingTop()); 
    } else { 
     return view.getScrollY() > 0; 
    } 
    } else { 
    return ViewCompat.canScrollVertically(view, -1); 
    } 
} 

如果傳入視圖是自定義視圖,則可能需要添加自定義邏輯。

+1

請注意,CanScrollVertically和canScrollHorizo​​ntally的ViewCompat方法總是在ICS下的平臺級別上返回false。該實現將這些方法設置爲返回false,除非被覆蓋,並且只有ICS的impl覆蓋方法。 – lillicoder

+0

@lillicoder你說得對。我們不能在較老的平臺上使用這些實現。我編輯了答案,使其適用於所有平臺。 – topduo

0

Graeme的答案很接近但缺少user2036198添加的內容,對getFirstVisiblePosition()進行檢查。 getChildAt(0)不返回列表中第一個項目的第一個視圖。 AbsListView實現不會爲每個位置製作單個視圖,並將它們全部保存在內存中。相反,查看回收會生效,以限制任何時候實例化的視圖數量。

修復的方法是非常簡單的:

public boolean canScrollVertically(AbsListView view) { 
    boolean canScroll = false; 

    if (view != null && view.getChildCount() > 0) { 
     // First item can be partially visible, top must be 0 for the item 
     canScroll = view.getFirstVisiblePosition() != 0 || view.getChildAt(0).getTop() != 0; 
    } 

    return canScroll; 
} 

有關ICS或更高最好的結果,總是從V4支持庫或View.canScrollVertically()使用ViewCompat。在較低的API級別使用上述方法,因爲ViewCompat對於canSrollVertically()和canScrollHorizo​​ntally()在ICS下總是返回false。

0

如果您可以直接擴展ListView,那麼您可以在覆蓋方法「onScrollChanged()」內使用名爲「computeVerticalScrollOffset()」的受保護方法。

使用該受保護的方法返回0,意味着您的ListView現在已到達頂部。

代碼段

 listView = new ListView(this){ 
     @Override 
     protected void onScrollChanged(int l, int t, int oldl, int oldt) { 
      super.onScrollChanged(l, t, oldl, oldt); 

      if(computeVerticalScrollOffset() == 0){ 
       // Reach top 
      } 
     } 
1

這個問題是舊的,但我有一個完美的作品的解決方案,這是可能的,有人尋找一個解決方案工作。

int limitRowsBDshow = 10; //size limit your list 
listViewMessages.setOnScrollListener(new AbsListView.OnScrollListener() { 
     int counter = 1; 
     int currentScrollState; 
     int currentFirstVisibleItem; 
     int currentVisibleItemCount; 
     int currentTotalItemCount; 


     @Override 
     public void onScrollStateChanged(AbsListView view, int scrollState) { 
      this.currentScrollState = scrollState; 
      this.isScrollCompleted(); 
     } 

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

      this.currentFirstVisibleItem = firstVisibleItem; 
      this.currentVisibleItemCount = visibleItemCount; 
      this.currentTotalItemCount = totalItemCount; 
     } 

     private void isScrollCompleted() { 
      if (this.currentVisibleItemCount > 0 && this.currentScrollState == SCROLL_STATE_IDLE) { 
       /*** detect if there's been a scroll which has completed ***/ 

       counter++; 
       if (currentFirstVisibleItem == 0 && currentTotalItemCount > limitRowsBDshow - 1) { 
        linearLay20msgMas.setVisibility(View.VISIBLE); 
       } 
      } 
     } 
    }); 

此代碼是前一次發現的(這裏是StackOverflow)。但我不能找到這個提

11

我的朋友們,結合格雷姆的回答與onScroll方法...

listView.setOnScrollListener(new AbsListView.OnScrollListener() { 
    @Override 
    public void onScrollStateChanged(AbsListView view, int scrollState) { 

    } 

    @Override 
    public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { 
     if(firstVisibleItem == 0 && listIsAtTop()){ 
      swipeRefreshLayout.setEnabled(true); 
     }else{ 
      swipeRefreshLayout.setEnabled(false); 
     } 
    } 
}); 


private boolean listIsAtTop() { 
    if(listView.getChildCount() == 0) return true; 
    return listView.getChildAt(0).getTop() == 0; 
} 
+0

豎起大拇指提及swipeRefreshLayout。特別是我需要的。 – ralphgabb