4

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!

Daniele B
  • 19,801
  • 29
  • 115
  • 173

2 Answers2

2

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.

SuppressWarnings
  • 4,134
  • 4
  • 25
  • 33
  • can you please be a bit more specific about detecting the scrollbar using getLastVisiblePosition / getFirstVisiblePosition? thanks!!! – Daniele B Dec 09 '13 at 02:44
  • I think those method return the int position of the listview element that is visible on screen at the moment you execute that method. If I remember well you can play with those values and the lv.getCount() so if first/last visible position < lv.getCount then it means there is scroll to do. – SuppressWarnings Dec 09 '13 at 08:28
  • I can't find a simple way to determine whether the content is scrolling, just by using the first and last position. For example, if the adapter has 5 elements, and the first visible position is 0 and the last visible position is 4, it could still be that either the first of the last view is not fully visible, so there would be a scrollbar. – Daniele B Dec 09 '13 at 17:41
0

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.

Robin
  • 10,052
  • 6
  • 31
  • 52
  • what do you test exactly? if the first visible position is 0 and the last visible position is the the last index of the adapter? What about if that's true but one of the two items is not fully visible? In such case the scrollbar would still appear. – Daniele B Dec 08 '13 at 15:05