Setting ListView scroll position nicely in Android

I am aware of setSelection(), setSelectionFromTop(), and setSelectionAfterHeaderView(), but none of them seems to do what I want.

Given an item in the list, I want to scroll so that it is in view. If the item is above the visible window of the list, I want to scroll until the item is the first visible item in the list; if the item is below the visible window, I want it to scroll up until it is the last visible item in the list. If the item is already visible, I don’t want any scrolling to occur.

  • Android Google Maps v2 inside Scrollview shows gray tiles on some devices
  • Animate layout change of bottom sheet
  • Android - Face feature detection
  • Android - width and height of bitmap without loading it
  • Programmatically set left drawable in a TextView
  • Android Studio failed build NDK project non-zero exit value
  • How do I go about this?

    Related posts:

    Android: adb pull file on desktop
    Android Offline Request with Volley
    Custom Collapsing Toolbar smooth title resizing
    Android Emulator: Installation error: INSTALL_FAILED_VERSION_DOWNGRADE
    How to change letter spacing in a Textview?
    Gradle error: “Attribute ”rippleColor“ has already been defined&rd...
  • AOSP Privileged vs System app
  • CalendarView Android Help
  • Make Notification Large Icon Round
  • Is it possible to disable following redirects in OkHttp 2.0?
  • IllegalStateException: Content has been consumed
  • Guideline to choose among AsyncTaskLoader and AsyncTask to be used in Fragment
  • 4 Solutions collect form web for “Setting ListView scroll position nicely in Android”

    It occurs because listView isn’t created yet. Try to post runnable such as:

    getListView().postDelayed(new Runnable() {          
        @Override
        public void run() {
            lst.setSelection(15);
        }
    },100L);
    

    I think, I was looking for the same, then I found the following solution:

    if (listview.getFirstVisiblePosition() > pos 
        || listview.getLastVisiblePosition() <= pos) {
        listview.smoothScrollToPosition(pos);
    }
    

    API 8 is required to use smoothScrollToPosition (which is a reasonable minimum anyways) so you are aware.

    Sergey’s answer works, but I believe that the right way of doing this is setting up an observer to be notified when the ListView has been created.

    listView.getViewTreeObserver().addOnGlobalLayoutListener(
         new ViewTreeObserver.OnGlobalLayoutListener() {
     @Override
     public void onGlobalLayout() {
         scrollTo(scrollToPosition);
         listView.getViewTreeObserver().removeGlobalOnLayoutListener(this);
     }
    });
    

    A better solution to Sergey’s answer is to call setSelection() later in the Activity/Fragment life cycle, perhaps in onStart(). That way, you have a guarantee that the View is ready rather than using some arbitrary delay.

    Android Babe is a Google Android Fan, All about Android Phones, Android Wear, Android Dev and Android Games Apps and so on.