Finden Sie heraus, ob ListView nach unten gescrollt ist?

105

Kann ich herausfinden, ob meine ListView nach unten gescrollt ist? Damit meine ich, dass der letzte Punkt vollständig sichtbar ist.

fhucho
quelle

Antworten:

171

Bearbeitet :

Da ich mich in einer meiner Bewerbungen mit diesem speziellen Thema befasst habe, kann ich eine erweiterte Antwort für zukünftige Leser dieser Frage schreiben.

Implementieren Sie eine OnScrollListener, stellen Sie Ihre ListViewein onScrollListenerund dann sollten Sie in der Lage sein, die Dinge richtig zu handhaben.

Beispielsweise:

private int preLast;
// Initialization stuff.
yourListView.setOnScrollListener(this);

// ... ... ...

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

    switch(lw.getId()) 
    {
        case R.id.your_list_id:     

            // Make your calculation stuff here. You have all your
            // needed info from the parameters of this function.

            // Sample calculation to determine if the last 
            // item is fully visible.
            final int lastItem = firstVisibleItem + visibleItemCount;

            if(lastItem == totalItemCount)
            {
                if(preLast!=lastItem)
                {
                    //to avoid multiple calls for last item
                    Log.d("Last", "Last");
                    preLast = lastItem;
                }
            }
    }
}
Wroclai
quelle
26
Dadurch wird nicht erkannt, ob das letzte Element vollständig sichtbar ist.
Fhucho
1
Wenn Sie Kopf- oder Fußzeilen in Ihrer Listenansicht haben, müssen Sie dies ebenfalls berücksichtigen.
Martin Marconcini
5
@Wroclai Hiermit wird nicht erkannt, ob das letzte Element vollständig sichtbar ist.
Gaurav Arora
Ich habe nach einem ähnlichen WORKING-Code gesucht. Es hat funktioniert !! Vielen Dank!!
Suraj Dubey
Ich möchte keine neue Frage stellen, aber was mache ich, wenn meine listviewist stackFromBottom? Ich habe es versucht, if (0 == firstVisibleItem){//listviewtop}aber das wird immer wieder aufgerufen.
Shadyinside
68

Späte Antwort, aber wenn Sie einfach überprüfen möchten, ob Ihre ListView ganz nach unten gescrollt ist oder nicht, ohne einen Ereignis-Listener zu erstellen, können Sie diese if-Anweisung verwenden:

if (yourListView.getLastVisiblePosition() == yourListView.getAdapter().getCount() -1 &&
    yourListView.getChildAt(yourListView.getChildCount() - 1).getBottom() <= yourListView.getHeight())
{
    //It is scrolled all the way down here

}

Zunächst wird geprüft, ob die zuletzt mögliche Position sichtbar ist. Anschließend wird überprüft, ob der untere Rand der letzten Schaltfläche mit dem unteren Rand der ListView übereinstimmt. Sie können etwas Ähnliches tun, um zu wissen, ob es ganz oben ist:

if (yourListView.getFirstVisiblePosition() == 0 &&
    yourListView.getChildAt(0).getTop() >= 0)
{
    //It is scrolled all the way up here

}
Martijn
quelle
4
Vielen Dank. Sie müssen nur ändern ... getChildAt (yourListView.getCount () -1) ... in ... getChildAt (yourListView.getChildCount () -1) ...
OferR
@OferR Nicht sicher, aber ich denke, getChildCount()die Ansichten in der Ansichtsgruppe werden zurückgegeben, was beim Ansichtsrecycling nicht mit der Anzahl der Elemente im Adapter übereinstimmt. Da ListView jedoch von AdapterView abstammt, können Sie es getCount()direkt in ListView verwenden.
William T. Mallard
@ William T. Mallard Dein erster Satz ist korrekt und genau das wollen wir: Die letzte Ansicht, die in der Gruppe angezeigt wird. Hiermit wird überprüft, ob es vollständig sichtbar ist. (Betrachten Sie eine ListView mit 20 Zeilen, aber nur die letzten 8 werden angezeigt. Wir möchten die 8. Ansicht in der ViewGroup erhalten, nicht die 20., die nicht existiert.)
OferR
Beachten Sie, dass diese Lösung nicht funktioniert, wenn Sie die Listenansicht schnell aktualisieren.
Eichhörnchen
19

So wie ich es gemacht habe:

listView.setOnScrollListener(new AbsListView.OnScrollListener() {

    @Override
    public void onScrollStateChanged(AbsListView view, int scrollState) {
        if (scrollState == AbsListView.OnScrollListener.SCROLL_STATE_IDLE 
            && (listView.getLastVisiblePosition() - listView.getHeaderViewsCount() -
            listView.getFooterViewsCount()) >= (adapter.getCount() - 1)) {

        // Now your listview has hit the bottom
        }
    }

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

    }
});
t-gao
quelle
1
Es ist toll! Danke
Shariful Islam
10

Etwas zu bewirken von:

if (getListView().getLastVisiblePosition() == (adapter.items.size() - 1))
Chris Stewart
quelle
1
Dadurch wird nicht erkannt, ob das letzte Element vollständig sichtbar ist.
Duanniston Cardoso Cabral
6
public void onScrollStateChanged(AbsListView view, int scrollState)        
{
    if (!view.canScrollList(View.SCROLL_AXIS_VERTICAL) && scrollState == SCROLL_STATE_IDLE)    
    {
        //When List reaches bottom and the list isn't moving (is idle)
    }
}

Das hat bei mir funktioniert.

Janwilx72
quelle
1
view.canScrollList Methode ist API 19+ nur leider
Ozmank
Funktioniert wie ein Zauber
pavaniiitn
4

Das kann sein

            @Override
            public void onScrollStateChanged(AbsListView view, int scrollState) {
                // TODO Auto-generated method stub

                if (scrollState == 2)
                    flag = true;
                Log.i("Scroll State", "" + scrollState);
            }

            @Override
            public void onScroll(AbsListView view, int firstVisibleItem,
                    int visibleItemCount, int totalItemCount) {
                // TODO Auto-generated method stub
                if ((visibleItemCount == (totalItemCount - firstVisibleItem))
                        && flag) {
                    flag = false;



                    Log.i("Scroll", "Ended");
                }
            }
fauler Herr
quelle
3

Es war ziemlich schmerzhaft, mit dem Scrollen umzugehen, zu erkennen, wann es fertig ist, und es befindet sich tatsächlich am Ende der Liste (nicht am unteren Rand des sichtbaren Bildschirms) und löst meinen Dienst nur einmal aus, um Daten aus dem Web abzurufen. Allerdings funktioniert es jetzt gut. Der Code lautet wie folgt für alle, die sich der gleichen Situation gegenübersehen.

HINWEIS: Ich musste meinen adapterbezogenen Code in onViewCreated anstelle von onCreate verschieben und das Scrollen hauptsächlich so erkennen:

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

public void onScrollStateChanged(AbsListView view, int scrollState) {
    if (getListView().getLastVisiblePosition() == (adapter.getCount() - 1))
        if (RideListSimpleCursorAdapter.REACHED_THE_END) {
            Log.v(TAG, "Loading more data");
            RideListSimpleCursorAdapter.REACHED_THE_END = false;
            Intent intent = new Intent(getActivity().getApplicationContext(), FindRideService.class);
            getActivity().getApplicationContext().startService(intent);
        }
}

Hier ist RideListSimpleCursorAdapter.REACHED_THE_END eine zusätzliche Variable in meinem SimpleCustomAdapter, die wie folgt festgelegt ist:

if (position == getCount() - 1) {
      REACHED_THE_END = true;
    } else {
      REACHED_THE_END = false;
    }

Nur wenn beide Bedingungen erfüllt sind, bedeutet dies, dass ich tatsächlich ganz unten auf der Liste stehe und mein Dienst nur einmal ausgeführt wird. Wenn ich REACHED_THE_END nicht abfange, wird der Dienst auch beim Zurückblättern erneut ausgelöst, solange das letzte Element angezeigt wird.

Zeeshan
quelle
Ich habe das andere losgeworden, weil es mir Probleme bereitete, aber insgesamt eine gute Antwort
Mike Baglio Jr.
3

canScrollVertically(int direction)funktioniert für alle Ansichten und scheint das zu tun, was Sie gefragt haben, mit weniger Code als die meisten anderen Antworten. Geben Sie eine positive Zahl ein, und wenn das Ergebnis falsch ist, sind Sie ganz unten.

dh:

if (!yourView.canScrollVertically(1)) { //you've reached bottom }

Joel H.
quelle
2

Um eine der oben genannten Antworten ein wenig zu erweitern, musste ich Folgendes tun, damit sie vollständig funktioniert. In ListViews scheint ein integrierter Abstand von ca. 6 dp vorhanden zu sein, und onScroll () wurde aufgerufen, als die Liste leer war. Dies behandelt beide Dinge. Es könnte wahrscheinlich ein bisschen optimiert werden, ist aber aus Gründen der Klarheit mehr geschrieben.

Randnotiz: Ich habe verschiedene Konvertierungstechniken von dp zu Pixel ausprobiert, und diese dp2px () war die beste.

myListView.setOnScrollListener(new OnScrollListener() {
    public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
        if (visibleItemCount > 0) {
            boolean atStart = true;
            boolean atEnd = true;

            View firstView = view.getChildAt(0);
            if ((firstVisibleItem > 0) ||
                    ((firstVisibleItem == 0) && (firstView.getTop() < (dp2px(6) - 1)))) {
                // not at start
                atStart = false;
            }

            int lastVisibleItem = firstVisibleItem + visibleItemCount;
            View lastView = view.getChildAt(visibleItemCount - 1);
            if ((lastVisibleItem < totalItemCount) ||
                    ((lastVisibleItem == totalItemCount) &&
                            ((view.getHeight() - (dp2px(6) - 1)) < lastView.getBottom()))
                    ) {
                        // not at end
                    atEnd = false;
                }

            // now use atStart and atEnd to do whatever you need to do
            // ...
        }
    }
    public void onScrollStateChanged(AbsListView view, int scrollState) {
    }
});

private int dp2px(int dp) {
    return (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, getResources().getDisplayMetrics());
}
CSX321
quelle
2

Ich kann noch keinen Kommentar abgeben, weil ich nicht genug Ruf habe, aber in der Antwort von @Ali Imran und @Wroclai denke ich, dass etwas fehlt. Mit diesem Code wird das Protokoll nach dem Aktualisieren von preLast nie wieder ausgeführt. In meinem speziellen Problem möchte ich jedes Mal, wenn ich nach unten scrolle, eine Operation ausführen. Sobald preLast jedoch auf LastItem aktualisiert wurde, wird diese Operation nie wieder ausgeführt.

private int preLast;
// Initialization stuff.
yourListView.setOnScrollListener(this);

// ... ... ...

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

switch(lw.getId()) {
    case android.R.id.list:     

        // Make your calculation stuff here. You have all your
        // needed info from the parameters of this function.

        // Sample calculation to determine if the last 
        // item is fully visible.
         final int lastItem = firstVisibleItem + visibleItemCount;
       if(lastItem == totalItemCount) {
          if(preLast!=lastItem){ //to avoid multiple calls for last item
            Log.d("Last", "Last");
            preLast = lastItem;
          }
       } else {
            preLast = lastItem;
}

}}

Mit diesem "else" können Sie jetzt Ihren Code (in diesem Fall Log) jedes Mal ausführen, wenn Sie erneut nach unten scrollen.

Teno Gonzalez Dos Santos
quelle
2
public void onScroll(AbsListView view, int firstVisibleItem,
                         int visibleItemCount, int totalItemCount) {
        int lastindex = view.getLastVisiblePosition() + 1;

        if (lastindex == totalItemCount) { //showing last row
            if ((view.getChildAt(visibleItemCount - 1)).getTop() == view.getHeight()) {
                //Last row fully visible
            }
        }
    }
John Ruban Singh
quelle
1

Wenn Ihre Liste aufgerufen wird, wenn die Liste das letzte Mal erreicht ist und ein Fehler auftritt, wird die Endoflist-Ansicht nicht erneut aufgerufen . Dieser Code hilft auch in diesem Szenario.

@Override
public void onScroll(AbsListView view, int firstVisibleItem,
        int visibleItemCount, int totalItemCount) {
    final int lastPosition = firstVisibleItem + visibleItemCount;
    if (lastPosition == totalItemCount) {
        if (previousLastPosition != lastPosition) { 

            //APPLY YOUR LOGIC HERE
        }
        previousLastPosition = lastPosition;
    }
    else if(lastPosition < previousLastPosition - LIST_UP_THRESHOLD_VALUE){
        resetLastIndex();
    }
}

public void resetLastIndex(){
    previousLastPosition = 0;
}

Dabei kann LIST_UP_THRESHOLD_VALUE ein beliebiger ganzzahliger Wert sein (ich habe 5 verwendet), bei dem Ihre Liste nach oben gescrollt wird. Wenn Sie zum Ende zurückkehren, wird das Ende der Listenansicht erneut aufgerufen.

Vyshnavi
quelle
1

Ich habe eine sehr gute Möglichkeit gefunden, das nächste Seitenset automatisch so zu laden, dass es kein eigenes erfordert ScrollView(wie es die akzeptierte Antwort erfordert).

In ParseQueryAdapter gibt es eine Methode namens getNextPageView, mit der Sie Ihre eigene benutzerdefinierte Ansicht bereitstellen können, die am Ende der Liste angezeigt wird, wenn mehr Daten geladen werden müssen, sodass sie erst ausgelöst wird, wenn Sie das Ende Ihres aktuellen Seitensatzes erreicht haben (Dies ist standardmäßig die Ansicht "Mehr laden ..."). Diese Methode wird nur aufgerufen, wenn mehr Daten geladen werden müssen. Daher ist dies ein großartiger Ort zum Aufrufen. Auf loadNextPage(); diese Weise erledigt der Adapter die ganze harte Arbeit für Sie, um zu bestimmen, wann neue Daten geladen werden sollen, und wird bei Bedarf überhaupt nicht aufgerufen hat das Ende des Datensatzes erreicht.

public class YourAdapter extends ParseQueryAdapter<ParseObject> {

..

@Override
public View getNextPageView(View v, ViewGroup parent) {
   loadNextPage();
   return super.getNextPageView(v, parent);
  }

}

Dann müssen Sie in Ihrer Aktivität / Ihrem Fragment nur noch den Adapter einstellen, und neue Daten werden automatisch wie von Zauberhand für Sie aktualisiert.

adapter = new YourAdapter(getActivity().getApplicationContext());
adapter.setObjectsPerPage(15);
adapter.setPaginationEnabled(true);
yourList.setAdapter(adapter);
Max Worg
quelle
1

Um festzustellen, ob das letzte Element vollständig sichtbar ist , können Sie einfach eine Berechnung am unteren sichtbaren Element der Ansicht unten hinzufügen lastItem.getBottom().

yourListView.setOnScrollListener(this);   

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

    int vH = view.getHeight();
    int topPos = view.getChildAt(0).getTop();
    int bottomPos = view.getChildAt(visibleItemCount - 1).getBottom();

    switch(view.getId()) {
        case R.id.your_list_view_id:
            if(firstVisibleItem == 0 && topPos == 0) {
                //TODO things to do when the list view scroll to the top
            }

            if(firstVisibleItem + visibleItemCount == totalItemCount 
                && vH >= bottomPos) {
                //TODO things to do when the list view scroll to the bottom
            }
            break;
    }
}
Wille
quelle
1

Ich ging mit:

@Override
public void onScroll(AbsListView listView, int firstVisibleItem, int visibleItemCount, int totalItemCount)
{
    if(totalItemCount - 1 == favoriteContactsListView.getLastVisiblePosition())
    {
        int pos = totalItemCount - favoriteContactsListView.getFirstVisiblePosition() - 1;
        View last_item = favoriteContactsListView.getChildAt(pos);

        //do stuff
    }
}
Goran Horia Mihail
quelle
1

In der Methode getView()(einer BaseAdapterabgeleiteten Klasse) kann überprüft werden, ob die Position der aktuellen Ansicht der Liste der Elemente in der entspricht Adapter. Wenn dies der Fall ist, bedeutet dies, dass wir das Ende / Ende der Liste erreicht haben:

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    // ...

    // detect if the adapter (of the ListView/GridView) has reached the end
    if (position == getCount() - 1) {
        // ... end of list reached
    }
}
Ramon
quelle
0

Ich finde einen besseren Weg, um das Bildlaufende der Listenansicht unten zu erkennen. Erkennen Sie zuerst das Ende des Bildlaufs durch diese
Implementierung von onScrollListener, um das Ende des Bildlaufs in einer Listenansicht zu erkennen

 public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
    this.currentFirstVisibleItem = firstVisibleItem;
    this.currentVisibleItemCount = visibleItemCount;
}

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

private void isScrollCompleted() {
    if (this.currentVisibleItemCount > 0 && this.currentScrollState == SCROLL_STATE_IDLE) {
        /*** In this way I detect if there's been a scroll which has completed ***/
        /*** do the work! ***/
    }
}

Kombiniere endlich Martijns Antwort

OnScrollListener onScrollListener_listview = new OnScrollListener() {       

        private int currentScrollState;
        private int currentVisibleItemCount;

        @Override
        public void onScrollStateChanged(AbsListView view, int scrollState) {
            // TODO Auto-generated method stub

            this.currentScrollState = scrollState;
            this.isScrollCompleted();
        }

        @Override
        public void onScroll(AbsListView lw, int firstVisibleItem,
                int visibleItemCount, int totalItemCount) {
            // TODO Auto-generated method stub
            this.currentVisibleItemCount = visibleItemCount;

        }

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

                if (listview.getLastVisiblePosition() == listview.getAdapter().getCount() - 1
                        && listview.getChildAt(listview.getChildCount() - 1).getBottom() <= listview.getHeight()) {
                    // It is scrolled all the way down here
                    Log.d("henrytest", "hit bottom");
                }


            }
        }

    };
HenryChuang
quelle
0

Vielen Dank an die Poster im Stackoverflow! Ich habe einige Ideen kombiniert und einen Klassen-Listener für Aktivitäten und Fragmente erstellt (daher ist dieser Code wiederverwendbarer, sodass Code schneller geschrieben und viel sauberer wird).

Alles, was Sie tun müssen, wenn Sie meine Klasse erhalten haben, ist, die in meiner Klasse deklarierte Schnittstelle (und natürlich die Erstellungsmethode dafür) zu implementieren und ein Objekt dieser Klasse zu erstellen, das Argumente übergibt.

/**
* Listener for getting call when ListView gets scrolled to bottom
*/
public class ListViewScrolledToBottomListener implements AbsListView.OnScrollListener {

ListViewScrolledToBottomCallback scrolledToBottomCallback;

private int currentFirstVisibleItem;
private int currentVisibleItemCount;
private int totalItemCount;
private int currentScrollState;

public interface ListViewScrolledToBottomCallback {
    public void onScrolledToBottom();
}

public ListViewScrolledToBottomListener(Fragment fragment, ListView listView) {
    try {
        scrolledToBottomCallback = (ListViewScrolledToBottomCallback) fragment;
        listView.setOnScrollListener(this);
    } catch (ClassCastException e) {
        throw new ClassCastException(fragment.toString()
                + " must implement ListViewScrolledToBottomCallback");
    }
}

public ListViewScrolledToBottomListener(Activity activity, ListView listView) {
    try {
        scrolledToBottomCallback = (ListViewScrolledToBottomCallback) activity;
        listView.setOnScrollListener(this);
    } catch (ClassCastException e) {
        throw new ClassCastException(activity.toString()
                + " must implement ListViewScrolledToBottomCallback");
    }
}

@Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
    this.currentFirstVisibleItem = firstVisibleItem;
    this.currentVisibleItemCount = visibleItemCount;
    this.totalItemCount = totalItemCount;
}

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

private boolean isScrollCompleted() {
    if (this.currentVisibleItemCount > 0 && this.currentScrollState == SCROLL_STATE_IDLE) {
        return true;
    } else {
        return false;
    }
}

private boolean isScrolledToBottom() {
    System.out.println("First:" + currentFirstVisibleItem);
    System.out.println("Current count:" + currentVisibleItemCount);
    System.out.println("Total count:" + totalItemCount);
    int lastItem = currentFirstVisibleItem + currentVisibleItemCount;
    if (lastItem == totalItemCount) {
        return true;
    } else {
        return false;
    }
}
}
Janusz Hain
quelle
0

Sie müssen Ihrer listView eine leere XML-Fußzeilenressource hinzufügen und feststellen, ob diese Fußzeile sichtbar ist.

    private View listViewFooter;
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View rootView = inflater.inflate(R.layout.fragment_newsfeed, container, false);

        listView = (CardListView) rootView.findViewById(R.id.newsfeed_list);
        footer = inflater.inflate(R.layout.newsfeed_listview_footer, null);
        listView.addFooterView(footer);

        return rootView;
    }

Dann tun Sie dies in Ihrem listView-Scroll-Listener

@
Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
  if (firstVisibleItem == 0) {
    mSwipyRefreshLayout.setDirection(SwipyRefreshLayoutDirection.TOP);
    mSwipyRefreshLayout.setEnabled(true);
  } else if (firstVisibleItem + visibleItemCount == totalItemCount) //If last row is visible. In this case, the last row is the footer.
  {
    if (footer != null) //footer is a variable referencing the footer view of the ListView. You need to initialize this onCreate
    {
      if (listView.getHeight() == footer.getBottom()) { //Check if the whole footer is visible.
        mSwipyRefreshLayout.setDirection(SwipyRefreshLayoutDirection.BOTTOM);
        mSwipyRefreshLayout.setEnabled(true);
      }
    }
  } else
    mSwipyRefreshLayout.setEnabled(false);
}

Joseph Mhanna
quelle
0

Wenn Sie ein Tag für eine Ansicht des letzten Elements der Listenansicht festlegen, können Sie später die Ansicht mit dem Tag abrufen. Wenn die Ansicht null ist, liegt dies daran, dass die Ansicht nicht mehr geladen wird. So was:

private class YourAdapter extends CursorAdapter {
    public void bindView(View view, Context context, Cursor cursor) {

         if (cursor.isLast()) {
            viewInYourList.setTag("last");
         }
         else{
            viewInYourList.setTag("notLast");
         }

    }
}

dann, wenn Sie wissen müssen, ob der letzte Artikel geladen ist

View last = yourListView.findViewWithTag("last");
if (last != null) {               
   // do what you want to do
}
Dante Carvalho Costa
quelle
0

Janwilx72 ist richtig, aber es ist min sdk ist 21, also erstelle ich diese Methode:

private boolean canScrollList(@ScrollOrientation int direction, AbsListView listView) {
    final int childCount = listView.getChildCount();
    if (childCount == 0) {
        return false;
    }

    final int firstPos = listView.getFirstVisiblePosition();
    final int paddingBottom = listView.getListPaddingBottom();
    final int paddingTop = listView.getListPaddingTop();
    if (direction > 0) {
        final int lastBottom = listView.getChildAt(childCount - 1).getBottom();
        final int lastPos    = firstPos + childCount;
        return lastPos < listView.getChildCount() || lastBottom > listView.getHeight() - paddingBottom;
    } else {
        final int firstTop = listView.getChildAt(0).getTop();
        return firstPos > 0 || firstTop < paddingTop;
    }
}

für ScrollOrientation:

protected static final int SCROLL_UP = -1;
protected static final int SCROLL_DOWN = 1;
@Retention(RetentionPolicy.SOURCE)
@IntDef({SCROLL_UP, SCROLL_DOWN})
protected @interface Scroll_Orientation{}

Vielleicht spät, nur für Spätankömmlinge。

Xiaoyee
quelle
0

Wenn Sie einen benutzerdefinierten Adapter mit Ihrer Listenansicht verwenden (die meisten Leute tun dies!), Wird hier eine schöne Lösung angegeben!

https://stackoverflow.com/a/55350409/1845404

Die getView-Methode des Adapters erkennt, wenn die Liste zum letzten Element gescrollt wurde. Außerdem werden Korrekturen für die seltenen Fälle hinzugefügt, in denen eine frühere Position aufgerufen wird, selbst nachdem der Adapter die letzte Ansicht bereits gerendert hat.

Gbenroscience
quelle
0

Ich habe das gemacht und arbeite für mich:

private void YourListView_Scrolled(object sender, ScrolledEventArgs e)
        {
                double itemheight = YourListView.RowHeight;
                double fullHeight = YourListView.Count * itemheight;
                double ViewHeight = YourListView.Height;

                if ((fullHeight - e.ScrollY) < ViewHeight )
                {
                    DisplayAlert("Reached", "We got to the end", "OK");
                }
}
Ahmed Osman
quelle
-5

Dadurch wird Ihre Liste bis zum letzten Eintrag nach unten gescrollt.

ListView listView = new ListView(this);
listView.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT,LayoutParams.FILL_PARENT));
listView.setTranscriptMode(ListView.TRANSCRIPT_MODE_ALWAYS_SCROLL);
listView.setStackFromBottom(true);
Salman Khalid
quelle