2011-09-06 11 views
27

मेरे पास एक सूची दृश्य है, पहले इसे स्क्रॉल किया गया है, अब जब हम स्क्रॉल करते हैं, तो यह शीर्ष बिंदु तक पहुंच जाता है। मैं इसका पता लगाना चाहता हूं। क्या कोई रास्ता है? मैं एपीआई स्तर के साथ आवेदन विकसित कर रहा हूं 8. पीएलएस मदद ..कैसे पता लगाएं कि ListView शीर्ष पर स्क्रॉल किया गया है अधिकतर स्थिति?

उत्तर

36

संपादित

नीचे टिप्पणी देखने के लिए क्यों, विशेष रूप से विभिन्न API संस्करण (खासकर बाद वाले) पर, यह एक सरल तरीका नहीं है के रूप में देखने के लिए अगर आप सूची रहे शीर्ष (गद्दी आदि पर है)। हालांकि, यह एपीआई 14 नीचे उपकरणों पर एक समाधान के लिए आप एक शुरुआत देता है:

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

जहाँ तक मेरी कार्यान्वयन साल पहले के रूप में - यह पूरी तरह से समय पर काम किया।

+0

अच्छा नहीं है ... स्वच्छ और सरल – Houston

+5

यह हमेशा मेरे लिए – JackMahoney

+0

(आप जोड़ सकते हैं ... getTop के लिए सूची के शीर्ष पर 0 वापस नहीं आता है()> 0 || ... getTop() Graeme

1

आप OnScrollListener का उपयोग कर सकते हैं ताकि स्थिति 0 अब दिखाई दे। onScroll विधि का उपयोग करें।

+5

मेरी सूची आइटम है वास्तव में बड़ी, तो मैं नहीं कर सकते, तो देखने के लिए की तुलना firstVisibleItem 0 है, क्योंकि आइटम आधे स्क्रीन को कवर करता है। अगर आइटम केवल आधा दिखाई देता है (शीर्ष में)। तो पहले भी VisualItem 0 है, जो सूची दृश्य में सबसे ऊपर नहीं है। – 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

आप पहली बार दिखाई स्थिति तब ग्रीम के समाधान को लागू करने अगर पहला दृश्य सूचीदृश्य आइटम शीर्ष स्थान पर है देखने के लिए है कि क्या जांच करने के लिए की आवश्यकता होगी।

कुछ की तरह lv.getFirstVisiblePosition() == 0 & & (lv.getChildCount() == 0 || lv.getChildAt (0) .getTop() == 0)

21

मैं इस सवाल का पता पुराना है, लेकिन यह Google खोज परिणामों में शीर्ष पर दिखाई देता है। वहाँ एक नई विधि एपीआई स्तर 14 में शुरू कर देता है कि हम वास्तव में क्या जरूरत है:

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

बड़े प्लेटफार्म के लिए एक v4 समर्थन पुस्तकालय में ViewCompat के समान स्थिर तरीकों का उपयोग कर सकते हैं। नीचे संपादित देखें।

ग्रीम की विधि के विपरीत, यह विधि 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 के लिए ViewCompat विधियां और canScrollHorizontally हमेशा आईसीएस के नीचे प्लेटफ़ॉर्म स्तर पर झूठी वापसी कर सकते हैं। कार्यान्वयन उन तरीकों को झूठी लौटने के लिए सेट करता है जब तक कि ओवरराइड न हो और केवल आईसीएस के लिए इंप्राइड विधियों को ओवरराइड करता है। – lillicoder

+0

@Lillicoder आप सही हैं। हम पुराने प्लेटफॉर्म पर कार्यान्वयन का उपयोग नहीं कर सकते हैं। मैंने जवाब को सभी प्लेटफार्मों के लिए काम करने के लिए संपादित किया है। – topduo

0

ग्रीम का जवाब करीब है लेकिन कुछ ऐसा याद आ रहा है जो उपयोगकर्ता 2036198 जोड़ा गया है, फर्स्टविज़िबलपोजिशन() के लिए एक चेक। 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; 
} 

आईसीएस या उच्चतर पर सर्वोत्तम परिणामों के लिए, हमेशा ViewCompat v4 समर्थन पुस्तकालय या View.canScrollVertically() से उपयोग करें। निचले एपीआई स्तरों पर उपर्युक्त विधि का उपयोग करें क्योंकि ViewCompat हमेशा canScrollVertically() के लिए झूठी रिटर्न देता है और आईसीएस के नीचे canScrollHorizontally() कर सकता है।

0

यदि आप सीधे सूची दृश्य को बढ़ा सकते हैं, तो आप ओवरराइड विधि "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

संबंधित मुद्दे