9

I set a timer in my app, I could get some information from a web service and resulted in a list view to display. Now my problem is that every time the timer runs, scroll back to the beginning ...

how can i keep Scroll position with every refresh in list view ?

part of my code:

runOnUiThread(new Runnable() {
    public void run() {
        /**
         * Updating parsed JSON data into ListView
        * */
        ListAdapter adapter = new SimpleAdapter(DashboardActivity.this, 
                                                all_chat, 
                                                R.layout.list_item, 
                                                new String[] { TAG_FULLNAME,
                                                               TAG_DATE, 
                                                               TAG_MESSAGE }, 
                                                new int[] { R.id.fullname,
                                                            R.id.date, 
                                                            R.id.message }
                                               );
        // updating listview
        setListAdapter(adapter);
    }
});

TNx.

5
  • stackoverflow.com/a/3035521/931982 Commented Apr 18, 2013 at 20:41
  • possible duplicate of Maintain/Save/Restore scroll position when returning to a ListView Commented Apr 18, 2013 at 20:41
  • These links do not solve my problem, Because my problem is another thing. my listview Automatically receives a data from Web service and then Scroll position back to the beginning (top position)...., I hope u undrestan me ... tnx. Commented Apr 18, 2013 at 21:38
  • 6
    cmon people, he sets every time new adapter, he should update it instead or use function like addElement and then calling notifyDataSetChange.. After second look at your problem you should do something like this: call clear, call add element in loop, call notifydatasetchange. Clearing depends if your elements are always new or just the same with some new Commented Oct 4, 2013 at 9:08
  • Setting adapter every time seems evil but still people keep doing it... Commented Oct 9, 2013 at 18:44

4 Answers 4

14
+25

Do not call setAdapter(). Do something like this:

ListAdapter adapter; // declare as class level variable

runOnUiThread(new Runnable() {
    public void run() {
        /**
         * Updating parsed JSON data into ListView
         */
        if (adapter == null) {
            adapter = new SimpleAdapter(
                    DashboardActivity.this, all_chat, R.layout.list_item, new String[]{TAG_FULLNAME, TAG_DATE, TAG_MESSAGE},
                    new int[]{R.id.fullname, R.id.date, R.id.message});
            setListAdapter(adapter);
        } else {
            //update only dataset   
            allChat = latestetParedJson;
            ((SimpleAdapter) adapter).notifyDataSetChanged();
        }
        // updating listview
    }
});
Sign up to request clarification or add additional context in comments.

1 Comment

Are allChat and all_chat same variables? Passing allChat to adapter constructor and then changing allChat reference does not mean that allChat will be changed in adapter.
6

You can add the following attribute to your ListView in xml.

android:stackFromBottom="true"
android:transcriptMode="alwaysScroll" 

Add these attributes and your ListView will always be drawn at bottom like you want it to be in a chat.

or if you want to keep it at the same place it was before, replace alwaysScroll to normal

in the android:transcriptMode attribute. 

Cheers!!!

Comments

2

I had the same issue, tried a lot of things to prevent the list from changing its scroll position, including:

android:stackFromBottom="true"
android:transcriptMode="alwaysScroll"

and not calling listView.setAdapter(); None of it worked until I found this answer:

Which looks like this:

// save index and top position
int index = mList.getFirstVisiblePosition();
View v = mList.getChildAt(0);
int top = (v == null) ? 0 : (v.getTop() - mList.getPaddingTop());

// ...

// restore index and position
mList.setSelectionFromTop(index, top);

Explanation:

ListView.getFirstVisiblePosition() returns the top visible list item. But this item may be partially scrolled out of view, and if you want to restore the exact scroll position of the list you need to get this offset. So ListView.getChildAt(0) returns the View for the top list item, and then View.getTop() - mList.getPaddingTop() returns its relative offset from the top of the ListView. Then, to restore the ListView's scroll position, we call ListView.setSelectionFromTop() with the index of the item we want and an offset to position its top edge from the top of the ListView.

Comments

1

There's a good article by Chris Banes. For the first part, just use ListView#setSelectionFromTop(int) to keep the ListView at the same visible position. To keep the ListView from flickering, the solution is to simply block the ListView from laying out it's children.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.