16

I have been working on a ListViewidea where it keeps scrolling automatically with no user interaction and that is absolutely doable using the android APIs for instance smoothScrollToPositionFromTop.

I have implemented ListView BaseAdapter where it load items forever (almost) to get a non stopping self repeated ListView.

What I want to achieve here is to keep myListViewscrolling forever with certain speed (slow) to make items clear and readable while scrolling down, I not sure yet if ListView is my best choice here.

below is a snippet of what I am trying to do. the result is good somehow but it's not smooth enough, I can feel the ListView flickers.

I need to improve smoothness, efficiency and control the speed

new Thread(new Runnable() {

    @Override
    public void run() {
        int listViewSize = mListView.getAdapter().getCount();

        for (int index = 0; index < listViewSize ; index++) {
            mListView.smoothScrollToPositionFromTop(mListViewA.getLastVisiblePosition() + 100, 0, 6000);
            try {
                // it helps scrolling to stay smooth as possible (by experiment)
                Thread.sleep(60);
            } catch (InterruptedException e) {

            }
        }
    }
}).start();
Ahmad Kayyali
  • 8,233
  • 13
  • 49
  • 83
  • 1
    So what is the problem? You have achieved this functionality (infinite scrolling) but want to improve smoothness/efficiency/slow it down? – breadbin Dec 19 '12 at 12:43
  • define "not smooth enough". This could be due to your adapter part, some items may be slow to load. – njzk2 Dec 19 '12 at 12:52
  • @breadbin: updated, njzk2 "not smooth enough" I mean I can see the listview slowing and then scroll again which makes it lagging. I need the scrolling to be one shot and forever. – Ahmad Kayyali Dec 19 '12 at 13:00
  • I think it's problem in fill listview.just improve the your adapter and use viewHoledr mechanisam to fill listview. – Zala Janaksinh Dec 29 '12 at 04:58

2 Answers2

15

I suggest, thath your adapter implemented in effective way. so this code is just scrolls listview

you need to try another values of variables

final long totalScrollTime = Long.MAX_VALUE; //total scroll time. I think that 300 000 000 years is close enouth to infinity. if not enought you can restart timer in onFinish()

final int scrollPeriod = 20; // every 20 ms scoll will happened. smaller values for smoother

final int heightToScroll = 20; // will be scrolled to 20 px every time. smaller values for smoother scrolling

listView.post(new Runnable() {
                        @Override
                        public void run() {
                                new CountDownTimer(totalScrollTime, scrollPeriod ) {
                                    public void onTick(long millisUntilFinished) {
                                        listView.scrollBy(0, heightToScroll);
                                    }

                                public void onFinish() {
                                    //you can add code for restarting timer here
                                }
                            }.start();
                        }
                    });
Ahmad Kayyali
  • 8,233
  • 13
  • 49
  • 83
Berezovskyi
  • 364
  • 3
  • 5
  • it seems an elegant solution, I am not at my development machine right now to test it, I will let you know as soon as I can. – Ahmad Kayyali Dec 28 '12 at 17:41
  • 3
    there is no doubt that you deserve the bounty, but there is a concern about the `ListView` in my infinite adapter, when the listview scrollBy it seems `getView(...)` does not get called so I see empty cell after the last cell get scrolled, do I need to invalidate the `ListView` while scrolling? – Ahmad Kayyali Dec 30 '12 at 05:39
  • I wroted some test app for this http://pastebin.com/9fUTuR1u You were right - scrollBy scrolls Listview in incorrect way. But it worked for me in ScrollView. BTW, if you have a small number of items in list view, you can add more smoothiness to scrolling if you try ScrollView with Linearlayout in it with all your items. – Berezovskyi Dec 31 '12 at 15:18
  • I will try this on a `ScrollView` but that would defeat the purpose of the endless adapter. what do you think? – Ahmad Kayyali Jan 02 '13 at 05:23
  • @AhmadTK yes, if you have big number of items (more 15) you MUST use adapter to prevent OOM errors. Did you try my source code in pastebin? – Berezovskyi Jan 02 '13 at 11:04
  • 1
    I wrote time ago this blog post about how to auto scroll a ListView. I hope it helps. It will be easy to control the speed just changing dynamically the amount pixels scroll. http://blog.jpardogo.com/autoscroll-a-listview-with-listviewautoscrollhelper/ – jpardogo Aug 27 '14 at 09:44
  • 3
    @Ahmad Kayyali Just change listView.scrollBy(0, heightToScroll) to listView.scrollListBy(heightToScroll) and it will work with ListView. – Chris.Zou Dec 12 '14 at 07:24
  • 1
    Unfortunately scrollListBy requires API level 19, and i have min sdk set to 11. now what? – Jasper Jan 12 '15 at 10:10
-1

Here a few pointers : Simulate onFling() programmatically instead of detecting it (Android)

and Programmatically Fling ListView Android

It's hard to figure out what you call smooth enough in your case. Usually smoothness problems are related to a non optimal usage of listviews and troubles in either cell layouts or view creation / recycling inside the getView method of adapters.

Do you use a placeholder ? An important thing to consider is also Drawables usage.

I never achieved what you are looking for, but a simple idea that comes to mind is :

  • find a way to scroll the view of 1 position or 2.
  • use a ring buffer inside your adapter. For instance let's say you got 100 items in your list of items. Then at the beginning, item 0 of the listview is item 0 of your list. When listview is scrolled up of 1 item, then item 0 of listview should become item 1 in your list. Thus the problem would not be scrolling but more syncing with scrolling and displaying an endless list of items.
Community
  • 1
  • 1
Snicolas
  • 37,840
  • 15
  • 114
  • 173
  • Thank you very much for taking the effort answering my question, let's talk about it: **1st** first link uses `InstrumentationTestCase` which I believe I can't use it in my app I mean on a regular Activity (correct me if I am wrong). **2nd** the other link has nothing to do with my problem, I have passed the auto scrolling issue/implementation. **3rd** Yes absolutely I am using place holders. **4th** I have zero concern implementing endless adapter :) – Ahmad Kayyali Dec 26 '12 at 07:56
  • what about slowing down ListView auto scrolling? – Ahmad Kayyali Dec 26 '12 at 08:00
  • You could give a try to scrolling by offset instead of positions : http://developer.android.com/reference/android/widget/ListView.html#smoothScrollByOffset(int) – Snicolas Dec 26 '12 at 10:17
  • for the sake of argument let say `scrolling by offset` have worked, how am I going to slow the scrolling speed? – Ahmad Kayyali Dec 26 '12 at 13:33
  • decrease the pace at which you call this method. no ? – Snicolas Dec 26 '12 at 13:39