2012-06-23 2 views
16

Woher wissen Sie, ob Ihr ListView über genügend Einträge verfügt, um blättern zu können?Wie überprüfe ich, ob eine ListView eine scrollbare Anzahl von Items hat?

Zum Beispiel, wenn ich 5 Elemente in meinem ListView habe, wird alles auf einem einzigen Bildschirm angezeigt. Aber wenn ich 7 oder mehr habe, beginnt meine ListView zu scrollen. Woher weiß ich, ob meine Liste programmgesteuert geblättert werden kann?

+0

Warum müssen Sie das wissen? Schließlich kann sich die Antwort bei Orientierungsänderungen ändern, und die Antwort kann sich ändern, je nachdem, was in Ihren Zeilen steht (unterschiedliche Zeilenlayouts, 'wrap_content'-Höhenänderungen basierend auf Prosa). Was versuchst du zu erreichen? – CommonsWare

+0

5 Elemente können nicht auf hdpi 800x480 scrollen, aber kann auf ldpi 240x320 scrollen, lassen Sie Android kümmern sich um das Scrollen für Sie! In der Tat, CommonsWare Gedanken, die mir durch den Kopf gingen, meinte ich, - Warum willst du das machen? – t0mm13b

+0

@CommonsWare, absolut verstehe ich das. Ich möchte eine Fußzeile am Ende der Aktivität anzeigen. Wenn die ListView scrollt, möchte ich das Fußzeilenbild als Listenansicht der Fußzeile platzieren. Andernfalls kann ich die Sichtbarkeit einer anderen Fußzeile am Ende des Aktivitätslayouts festlegen. –

Antwort

-1

Verwenden Sie die setOnScrollListener, durch den Rückruf zu OnScrollListener anwenden, können Sie bestimmen, ob Scrollen stattfindet den vordefinierten Konstanten und die Situation entsprechend zu behandeln.

+0

Ich würde nur dann einen Rückruf erhalten, wenn das Ereignis eintritt, oder? Das Layout muss jedoch geändert werden, bevor der Benutzer versucht, durch die Liste zu blättern. –

1

Sie können dies nicht erkennen, bevor Android den Bildschirm mit der listView rendern. Sie können dieses Nachrendern jedoch absolut erkennen.

boolean willMyListScroll() {   
    if(listView.getLastVisiblePosition() + 1 == listView.getCount()) { 
     return false; 
    } 

    return true;    
} 

Was dies bedeutet, ist zu überprüfen, ob das listView sichtbare Fenster ALL Ihre Listenansicht Elemente enthält. Wenn dies der Fall ist, scrollt listView niemals und die getLastVisiblePosition() wird immer gleich der Gesamtzahl der Elemente im DataAdapter der Liste sein.

+0

Hallo, danke. Wenn jedoch das letzte Element auf dem Bildschirm halb sichtbar ist, wird auch die Listenansicht geblättert. –

+0

Würde der "+1" -Teil von Diegosans Antwort entfernt? –

+1

Nein, das wird seine Antwort nicht funktionieren lassen. Überprüfen Sie meine Antwort unten. –

13

Die Antwort von Diegosan kann nicht unterscheiden, wenn das letzte Element teilweise auf dem Bildschirm sichtbar ist. Hier ist eine Lösung für dieses Problem.

Zuerst muss die ListView auf dem Bildschirm gerendert werden, bevor wir überprüfen können, ob der Inhalt scrollbar ist.

ViewTreeObserver observer = listView.getViewTreeObserver(); 
    observer.addOnGlobalLayoutListener(new OnGlobalLayoutListener() { 

     @Override 
     public void onGlobalLayout() { 
      if (willMyListScroll()) { 
       // Do something 
      } 
     } 
    }); 

Und hier ist willMyListScroll(): Dies kann mit einem ViewTreeObserver erfolgen

Dies ist
boolean willMyListScroll() { 
    int pos = listView.getLastVisiblePosition(); 
    if (listView.getChildAt(pos).getBottom() > listView.getHeight()) { 
     return true; 
    } else { 
     return false; 
    } 
} 
+2

Ausgezeichnete Lösung - der Methode willMyListScroll() für getChildAt (pos) muss eine Nullprüfung hinzugefügt werden. Wenn die Liste leer ist, stürzt sie ab: D – HelloImKevo

+2

Ich glaube, das ist falsch. getChildAt() zählt nur die Kinder, die auf dem Bildschirm sichtbar sind. In der Zwischenzeit gibt getLastVisiblePosition den auf dem Adapter basierenden Index zurück. Wenn also die lastVisiblePosition 8 ist, weil es das 9. Element in der Liste ist und nur 4 sichtbare Objekte auf dem Bildschirm sind, wird es einen Absturz geben. Überprüfen Sie es, indem Sie getChildCount() aufrufen und sehen. Die Indizes für getChildAt sind nicht identisch mit den Indizes für den Datensatz. Überprüfen Sie dies: http://stackoverflow.com/questions/6766625/listview-getchildat-returning-null-for-visible-children – jacosta

0

, wie ich

if (listView.getAdapter() != null 
        && listView.getLastVisiblePosition() == listView.getAdapter().getCount() - 1 
        && listView.getChildAt(listView.getChildCount() - 1).getBottom() == listView.getBottom()) 

überprüfen verwendet, ob es wahr gibt, dann ist die Liste an der Boden

3

Laut meinem Kommentar zu Mike Ortiz 'Antwort, glaube ich, seine Antwort ist falsch:

getChildAt() zählt nur die untergeordneten Objekte, die auf dem Bildschirm sichtbar sind. In der Zwischenzeit gibt getLastVisiblePosition den auf dem Adapter basierenden Index zurück. Wenn also die lastVisiblePosition 8 ist, weil es das 9. Element in der Liste ist und nur 4 sichtbare Objekte auf dem Bildschirm sind, wird es einen Absturz geben. Überprüfen Sie es, indem Sie getChildCount() aufrufen und sehen. Die Indizes für getChildAt sind nicht identisch mit den Indizes für den Datensatz. Check this out: ListView getChildAt returning null for visible children

Hier ist meine Lösung:

public boolean isScrollable() { 
     int last = listView.getChildCount()-1; //last visible listitem view 
     if (listView.getChildAt(last).getBottom()>listView.getHeight() || listView.getChildAt(0).getTop()<0) { //either the first visible list item is cutoff or the last is cutoff 
       return true; 
     } 
     else{ 
      if (listView.getChildCount()==listView.getCount()) { //all visible listitem views are all the items there are (nowhere to scroll) 
       return false; 
      } 
      else{ //no listitem views are cut off but there are other listitem views to scroll to 
       return true; 
      } 
     } 
    } 
+0

Diese Lösung funktioniert auch, nachdem Sie zu einem Punkt auf der Liste gescrollt oder gedreht haben das Telefon. Es ist nicht auf einen Anruf direkt nach dem ersten Laden der Liste – jacosta

-2
boolean listBiggerThanWindow = appHeight - 50 <= mListView.getHeight(); 

      Toast.makeText(HomeActivity.this, "list view bigger that window? " + listBiggerThanWindow, Toast.LENGTH_LONG) 
        .show(); 

      if (listBiggerThanWindow) { 
       // do your thing here... 
       } 

Sie Dimensionen in onCreate bekommen können() durch den Aufruf von Post (Runnable) auf Ansicht.

+0

Sie appHeight - 50 beschränkt. Was ist appHeight, was ist sein Maß (px, dp, dip .. etc?). Bitte fügen Sie weitere Informationen hinzu. –

1

Dies ist der Code, den ich für die Ansicht ein Bild nach der letzten Zeile des Listview schrieb:

diese
public class ShowTheEndListview 
{ 
    private ImageView the_end_view; 
    private TabbedFragRootLayout main_layout; 
    private ListView listView; 
    private float pas; 
    private float the_end_img_height; 
    private int has_scroll = -1; 

    public ShowTheEndListview(float height) 
    { 
     the_end_img_height = height; 
     pas = 100/the_end_img_height; 
    } 

    public void setData(ImageView the_end_view, TabbedFragRootLayout main_layout, ListView listView) 
    { 
     this.the_end_view = the_end_view; 
     this.main_layout = main_layout; 
     this.listView = listView; 
    } 

    public void onScroll(int totalItemCount) 
    { 
     if(totalItemCount - 1 == listView.getLastVisiblePosition()) 
     { 
      int pos = totalItemCount - listView.getFirstVisiblePosition() - 1; 
      View last_item = listView.getChildAt(pos); 

      if (last_item != null) 
      { 
       if(listHasScroll(last_item)) 
       { 
//      Log.e(TAG, "listHasScroll TRUE"); 
       } 
       else 
       { 
//      Log.e(TAG, "listHasScroll FALSE"); 
       } 
      } 
     } 
    } 

    private boolean listHasScroll(View last_item) 
    { 
     if(-1 == has_scroll) 
     { 
      has_scroll = last_item.getBottom() > (main_layout.getBottom() - the_end_img_height - 5) ? 1 : 0; 
     } 

     return has_scroll == 1; 
    } 

    public void resetHasScroll() 
    { 
     has_scroll = -1; 
    } 
} 
1

AbsListView umfasst:

/** 
* Check if the items in the list can be scrolled in a certain direction. 
* 
* @param direction Negative to check scrolling up, positive to check scrolling down. 
* @return true if the list can be scrolled in the specified direction, false otherwise. 
* @see #scrollListBy(int) 
*/ 
public boolean canScrollList(int direction); 

Sie müssen außer Kraft setzen layoutChildren() und es verwenden, innerhalb davon:

@Override 
protected void layoutChildren() { 
    super.layoutChildren(); 
    isAtBottom = !canScrollList(1); 
    isAtTop = !canScrollList(-1); 
} 
Verwandte Themen