29

I've got a custom Adapter for a ListView setup and working ok. On a button click something is changed in the underlying data, so a notifyDataSetChanged is required to refresh the ListView. Fine. But I also want the ListView to scroll to the line where the change occurred. For this I call smoothScrollToPosition immediately after the notifyDataSetChanged. And that is not working.

If I do not call notifyDataSetChanged then the scroll works, so the notify blocks the scroll. I'm probably having a fight with events being processed in the future. Can anybody give me a pointer on what is going wrong?

tbeernot
  • 2,473
  • 4
  • 24
  • 31
  • 1
    A little bit of additional information; this behavior occurs on the emulator. When run on a phone the situation is mixed; sometime the scroll works and sometimes not. It seems to be a question of whether the notify is finished before the smooth is done. Or maybe in what order. – tbeernot Aug 04 '11 at 14:02

2 Answers2

91

Use the post() method to wait for the list to finish updating after you call notifyDataSetChanged():

adapter.notifyDataSetChanged();
list.post( new Runnable() {
    @Override
    public void run() {
    //call smooth scroll
    }
  });
dmon
  • 30,048
  • 8
  • 87
  • 96
  • Thank you! This works. On the emulator the list jumps to the end and then to where I told it to go to, but on a phone this is not visible. – tbeernot Aug 04 '11 at 17:29
  • In theory, the list should stay in the same position where it was before `notifyDatasetChanged()`, so if you refresh with less elements, it would effectively go to the end first. – dmon Aug 04 '11 at 17:33
  • Trials show that notifyDatasetChanged makes the list always jump to the bottom, the smoothScrollToPosition makes it jump so that the entry is at the top. On the emulator this is clearly visible, on an actual phone the list is "restless" and there is action when none is required. – tbeernot Aug 08 '11 at 04:49
  • I did try using firstChildVisible and childCount to minimize unneccessary scrolling, but since after notify the list is always at the end, scrolling almost always is neccessary. – tbeernot Aug 08 '11 at 04:50
  • Thanks.It works, I have used setSelection(int position) instead of smoothScrollToPosition. smoothScrollToPosition is not worked for me. – M.A.Murali Oct 15 '14 at 10:23
  • Thanks. you made my day. :-) – Dhaval Patel Oct 12 '15 at 04:19
0

I've tried the dmon's example code and I see it not always working.

Actually I've found another approach to perform scrolling:

adapter.notifyDataSetChanged();
channelsListView.setSelection(scrollPos); // it works without smoothScrollToPositionFromTop(..) or smoothScrollToPosition() methods call.

I found the main idea to use above method after this answer reading: https://stackoverflow.com/a/20997828/2133585

Community
  • 1
  • 1
Kirill Vashilo
  • 1,559
  • 1
  • 18
  • 27