What you need to do is roughly
listview.post(new Runnable() {
public void run() {
listview.getLastVisiblePosition();
}
});
Why this way and not directly?
Android apps run in a big event loop known as the UI / main thread. Everything that is executed in there is the result of some event. For example when your Activity
needs to be created that's some sort of Activity creation event. The loop will execute code that handles this event and will for example once your are considered "created" call the onCreate
method. It might call more than one method within the same iteration but that's not really important.
When you setup things like the UI in any of those onSomething
methods nothing is actually drawn directly. All you do is set some state variables like a new Adapter
. Once you return from those on
methods the system gains back control and will check what it needs to do next.
The system will for example check if the window needs to be redrawn and if so will enqueue a redraw event in the event queue which is at a later point executed by the loop. If nothing needs to be drawn it's just idle and will wait for example for touch events that are enqueued for that loop as well.
Back to your problem: By calling .setAdapter()
you essentially reset all states of the ListView
. And since actual updates of the ListView
will only happen after you hand control back to the system you will get nothing useful out of .getLastVisiblePosition()
.
What needs to happen before is that ListView
is instructed to be redrawn or to measure it's new size, count the amount of items it has and so on. Once it has done that it will be able to give you the required information.
.post(Runnable r)
simply enqueues a Runnable into the eventqueue which is then executed by the loop once it's first in the queue.
a Runnable
does not require a Thread
, it's just a regular Object with a method named run()
and the contract of a Runnable
is simply that something (which often happens to be a Thread
) can call the run()
method to execute whatever you want to run. Magical loop does that.
Result of you posting a runnable is looks inn pseudo code somewhat like this:
void loop() {
yourActivity.onSomething() { loop.enqueue(runnable) }
ListView.redraw() // |
runnable.run() // <--+
}