ListView: how do I wait until it's loaded up? - android

I'm using a ListView with an ArrayAdapter, and code executing after ListView.setAdapter(ArrayAdapter,...) is seeing ListView.getChildCount()==0.
Is there a way t wait for the UI thread to finish filling the ListView before continuing?
Thanks in advance,
Lenny

ListView.getChildCount() is inherited from ViewGroup and is not related to the items managed by the adapter but the child views managed by the ListView.
To get the number of items displayed by the ListView use getCount() which returns the number of items managed by the adapter.

I had a similar problem that I solved creating a thread that has while loops that can only go forward after the list is loaded.
new Thread(new Runnable() {
public void run() {
while(listView.getCount() == 0) ;
}
}).start();
This approach can be done cuz I garantee that at this point there is something in the list. Be carefull using this approach. It is not the best one but it was the one that I found.

Related

android listview make an item visible without using scroll

I have a listview with 150+ items, I need to make one visible from code. I currently use smoothscrolltoposition but when the desired item is far away from the current visible item it takes several seconds to arrive.
Is there anyway to simply get rid of the smooth scrolling and simply make the item visible directly?
Thanks,
Ignacio
You can use postdelayed for smooth scroll
listview.postDelayed(new Runnable() {
#Override
public void run() {
// smoothscrolltoposition
}
}, 100);
After several testing and reading the thread suggested by audi , I got this solution:
Strangely, the trick is in reassign the adapter to the listview, not even it is needed to recreate it, just reassign.
listView.Adapter = adapter;
listView.FastScrollEnabled = true;
listView.SetSelection(index);
adapter.NotifyDataSetChanged();

Android: Detect if a ListView has the scrollbar (after setting new data)

I have an ArrayAdapter linked to a ListView.
mListView.setAdapter(mArrayAdapter);
Whenever I reset the ArrayList data to the ArrayAdapter:
mArrayAdapter.clear();
mArrayAdapter.addAll(mArrayList);
mArrayAdapter.notifyDataSetChanged()
the ListView gets correctly updated
however, if just after the above three lines, I call my custom method mListView.hasScrollbar() to detect whether the listview has a scrollbar or not, I get a null lastVisibleItem:
public boolean hasScrollbar() {
View lastVisibleItem = (View) getChildAt(getChildCount() - 1);
if (lastVisibleItem.getBottom()>=getHeight()) {
return true;
}
return false;
}
does it mean that the listview is still refreshing?
My main question is:
how can I test if the listview has the scrollbar after resetting the adapter with new data?
thank you for any help!
Using getLastVisiblePosition / getFirstVisiblePosition is a valid method of detecting wether you have scrolling or not within the list view (aslong as you compare it to getCount() and do your math ofc).
The problem you have as you already guess is that you are attempting to check out of sync.
In order to sync your query when the adapter already filled your List Data and updated changes, you need to issue a post request to the list, which will stack that petition to the message queue of the adapter.
yourAdapter.notifyDataSetChanged();
yourAdapter.getListView().post(new Runnable() {
#Override public void run() {
//your code here
}
});
Make sure to call that after notifySetDataChanged() of course. Because you want the list to update before the check.
I think your question equals to "how to tell if list view contains items need to displayed on more than one screen"?
So my suggestion is to use listView.getFirstVisiblePosition() and getLastVisiblePosition() to tell it.

Alternative to ListView smoothScrollToPosition()?

I have a ListView that potentially can have hundreds of entries. When a selection is made I've been using a smoothScrollToPosition, thusly:
if (lv != null) { //Are we created yet?
lv.post(new Runnable() {
public void run() {
lv.smoothScrollToPosition(k);
}
});
}
but my users have told me they don't like the scrolling animation and would prefer to just instantly go there. So I replaced my smooth scroll with
lv.setSelection(k);
... and now it does nothing at all. FWIW this is all happening right after a notifyDatasetChanged
In searching for a solution I came across this discussion on http://code.google.com/p/android/issues/detail?id=6741 which implies this is a known problem. Is there a workaround or am I just doing this wrong?
Thanks in advance.
The documentation of setSelection says that it only scrolls to the selected position when the ListView is in touch mode. Maybe ListView is no more in touch mode once the data set has changed or maybe setSelection is simply forgotten for the next UI update cycle.
I guess you could try a workaround by calling setSelection with a delay. You could use the postDelayed method with a delay of 100 milliseconds for example. Or you could extend ListView and override layoutChildren or something related that probably gets called when the data set changes in order to re-calculate the list view item measurements. At that point it should be safe to call setSelection and you don't need to rely on guesstimating a delay.

Update ListView from adapter Instantly

I'm developing an application that shows stock market information. In my application I use listactivity and my own adapter is being used.
The listView used to show the stocks is working fine and is updated with correct data. The only problem is, although I use
adapter.notifyDataSetChanged();
the list isn't updated until scrolling and items subjected to change, are scrolled out from the screen. When they are scrolled in, they appear with new data.
I need to change the data as soon as I notify the adapter.
I have face same problem
but finally got solution
And its solution is
listView.invalidateViews();
I think for that you have to take the help of the Lazy ListView or Lazy Loader:
Check out the below link :
Lazy load of images in ListView
It will help you.
Are you calling notifyDataSetChanged in UI thread? If not: you can do the following:
runOnUiThread(new Runnable() {
public void run() {
adapter.notifyDataSetChanged();
}
});

Android: using notifyDataSetChanged and getLastVisiblePosition - when the listView is actually updated?

I want to use getLastVisiblePosition() and apparently it is not giving me the right number after this method (notifyDataSetChanged) has been called. I think this method only notifies the view that there is a change, but the change is triggered later.
When the view is updated, is there an event that I can use and trigger my method, using getLastVisiblePosition?
Please help or tell me what I am doing wrong ;)
Thanks
Danail
Yes, if you run notifyDatasetChanged(), you need to queue the operation in the post because the view is rendered asynchronously:
listView.post(new Runnable() {
public void run(){
lastPos = listView.getLastVisiblePosition();
}
});

Categories

Resources