Smooth Scrolling List

One of the features that got cut from 3.0 was “smooth scrolling”. List and other list-related classes scroll by row/column which can be a bit choppy at times. We tried to leave the hooks in to allow someone to do it, but we ran out of time to finish the job.
It’s too bad we didn’t finish the job as there are some difficult things to workaround in trying to get smooth scrolling to work, but I cooked this prototype up to give you a sense for how you might be able to get it working in your apps. Note that the prototype assumes that all rows are the same height. If you have variableRowHeight, that’s a whole different problem.
Usual caveats apply, and no, I don’t currently have time to make examples for TileList and DataGrid. Maybe some one else will have the time.
Download Source
Run Demo

50 Responses to Smooth Scrolling List

  1. Troy Gilbert says:

    It’s a real shame that smooth scrolling didn’t make it in. I see it as a big hole in the Flex UI framework considering its graphics/animations roots.
    I still don’t understand why its such a hard problem… would it not be implemented with just some number of offscreen rows and then a bit of scrollRect math? I even think the caveat that when the user stops scrolling the list “snaps” to a row (like your solution) is a fine compromise.
    ———————
    Alex responds:
    If you look at the code, you’ll see what was “hard”. The List classes make lots of assumptions that they are scrolled to integer scrollPositions, and ScrollThumb does as well. Plus, we would have been tasked with making this work for variableRowHeight=true, which would require some much fancier scrolling logic as you wouldn’t want to jump by 1/8 of a row for really tall rows or short rows as I do in this example.
    Maybe we could have placed restrictions that it wouldn’t work for variableRowHeight. BTW, you can probably get rid of the snap-to-row by adding THUMB_POSITION to the THUMB_TRACK case.

  2. Luke says:

    Are there any plans of adding mouse wheel support?
    ——————–
    Alex responds:
    No plans, but you’re welcome to do it and share how you did it.

  3. Thanks for this. The lack of smooth scrolling support is really obvious in cases where row height is high, for example in a TileList with a large itemRenderer. I was able to paste this directly into a component which extended TileList and got the desired behavior, with one bug: when the height of the list is less than the list’s rowHeght, the height of the scrollThumb is incorrect. However it is possible that something in my particular implementation is causing that…
    ————————
    Alex responds:
    Glad it works for TileList. I would not expect things to work correctly if you can’t see at least one full row.

  4. Michael says:

    I am trying to do this horizontally.
    var thumb:DisplayObject = horizontalScrollBar.getChildAt(2);
    trace(thumb.x);
    Any idea why thumb.x keeps returning 0?
    Thank you

  5. Michael says:

    Well, it is obvious. The scroll bar is rotated. So it is always is thumb.y.
    ——————-
    Yes it is. List already supports smooth scrolling horizontally. Are you trying to do this for DataGrid or TileList?

  6. Michael says:

    Thank you. Currently I am extending TileBase. List already supports smooth scrolling horizontally? How? I have to look a that.
    ——————
    Alex responds:
    List has only one “column” so if you set maxHorizontalScrollPosition, it will scroll by pixel and not by column.

  7. Al says:

    Have tried using this component for a horizontal list, setting columnCount to say 4 and rowCount to 1 – which works on a regular list.
    However, it still creates a as many rows as my dataProvider and creates a column with a single item in it on each row 4 columnWidths wide.
    Hope that makes sense.
    Am I missing something?
    —————————
    Alex responds:
    Are you subclassing List or HorizontalList? Someone said they got it working vertically with TileLIst, so you should be able to get to to work horizontally with TileList/HorizontalList

  8. John says:

    I can accept that if clicking on the down or up arrow the list scrolls one item. But what I can’t bear is when clicking beneath the scroll bar, it advances one item instead of the # of visible items. Makes for ugly scrolling. Is this difficult to fix or am I missing something?
    ——————————
    Alex responds:
    I’m not sure what you mean by “beneath the scrollbar”. When I run the demo, clicking beneath the thumb advances by a whole page.

  9. joerg says:

    Thanks for the smooth scrolling works very well!
    I have one problem with it: I want to zoom into the items of the list… that is working to a certain point by increasing the rowheight. anyway the width of the elements doesn’t extend the width of the list itself.
    I want them to be a kind of masked… by the bounderies of the list….
    ————————-
    Alex responds:
    If the scrollbar is up, the width of the renderers is masked at the scrollbar’s edge. The renderers can extend beyond that by setting horizontalScrollPolicy=”on” and setting maxHorizontalScrollPolicy

  10. nemke says:

    Thanks, this works great, just what I needed.

  11. Nate says:

    I’m trying to port this example to the Datagrid. I’m noticing that if I do a move on listContent in a DG the headers (as part of the listContent) bounce. I’ve looked through the docs and can’t seem to find a way to reference a group of itemRenderers excluding headerRenderers (unless I loop through listItems, which opens up a whole other rendering can of worms). Alex, would you know of an easier way to do this? Thanks in advance 🙂
    ——————————
    Alex responds:
    Sounds like you’re using Flex 2? In Flex 3 the headers are in a separate container.

  12. Thanks for this. I appreciate it!

  13. Poesco says:

    Works realy good. The only problem is that mousescrollwheel only works up and not down… Anyone have a solution for this?
    ————————-
    Alex responds:
    Good point, and mousewheel isn’t smooth going up. Maybe I’ll have time to look into it someday.

  14. One workaround — might not be appropriate for all cases, but in my case, it seems to suffice — is just setting the rowCount property on the TileList and then wrapping it in a Canvas control. You lose the delayed instantiation benefits, but in certain situations it might be a fine tradeoff for some folks. Figured I’d share, since I’ve been frustrated by this one myself for a while now.
    Cheers,
    Chris

  15. Thank you! Also, how can you add easing to the content? To get a springing effect?
    —————————
    Alex responds:
    Apply a moveeffect at the end of every scrollHandler that moves the y of the listContent.

  16. Mario says:

    Thanks for this post. Is there already a way to use smooth scrolling with variable row height? Any prototype or something? Will this feature be in the Flex 4 release? Thanks for your answer!
    ————————–
    Alex responds:
    We may do this for Flex 4. No guarantees

  17. dev says:

    what should i do to use smooth scrolling in advanced datagrid with variable row height?
    ————–
    Alex responds:
    You can try out this code and see how well it works in ADG. You’ll see that fat rows scroll faster than thin rows. How to make that smoother is a hard problem. Maybe we’ll solve it someday.

  18. Carl says:

    Great sample Alex. Is is possible to dispatch a scroll event in code? I am trying to create a scrolling marquee with this sample code — trying to simulate the user clicking on the down arrow in code. Any thoughts?
    ——————–
    Alex responds:
    You can certainly fake events like this from code. Look at the ScrollEvent doc and create an event with the appropriate properties and dispatch it on the List.

  19. In case anyone is interested, here is a very hacky way of creating a smooth scrolling datagrid that works:
    http://hash-pipe.com/2008/11/flex-smooth-scrolling-datagrid/

  20. Jayesh Sharma says:

    Hii there,
    I am new to flex and using itemrenderer for flex datagrid column and displaying images and text into the column of the flex data grid.
    When I scroll the datagrid then the images in the grid gets distorted i.e. sometimes images appear at proper row, sometimes bottom images appear at the very first row of the datagrid and sometimes images don’t even appear.
    Any suggestions are most welcome.
    Thanks in advance.
    ——————
    Alex responds:
    Read the posts in the item renderers category. Renderers are recycled and you’re describing typical recycling problems.

    • Danut says:

      Hello,
      I didn’t try with a DataGrid component, but in List the answer for a distorted item renderer is to set useVirtualLayout to false.
      The problem related to the appearance of data in item renderer is located in set data function. This could be resolved in this way:

      override public function set data(value:Object) : void {

      //set message content with some delay using setTimeout(setData, 100);
      }

  21. Jon says:

    In the getter for vertical scroll position, why did you set fudge back to NaN?
    ——————
    Alex responds:
    It is a handshake between scrollHandler and the getter just during smooth scrolling. Any other time someone gets the value it should be an integer value

  22. Lily says:

    Alex,
    Could you please elaborate a bit more on the tips for using this to create a Marquee? I’m new to Flex and trying to extend ScrollEvent don’t know what type of Event to pass to it? Please help. Thanks!
    ———————
    Alex responds:
    You shouldn’t need to extend ScrollEvent. Just see what kind of ScrollEvent normally gets dispatched on arrowDown or arrowUp and dispatch that same event from a timer

  23. Sosh says:

    Is smooth scrolling available in pure flash CS3/AS3 code? I do not have flex so need something that works on flash/as3. Any pointer would help me.
    ——————————
    Alex responds:
    Don’t know. If you don’t need virtualization, just create as many things as you need and use a scrollRect.

  24. rohit says:

    how can we emplement this with tile list?
    I tried but not working….
    any idea

  25. Constantin says:

    Hello!
    I have 1 problem with using the SmoothScrollingList. I’ve got 1 list with custom item renderers of different heights. When I scroll up and down the scroll bar gets messed up. Same does the position of the items in the list.
    Any suggestions? Workarounds except of having it all in a VBox? I could put all elements in a vbox and have a hidden list to do the hard work of sorting and manually reposition still if there is a way the list could work it’d be great.
    Thanks!

  26. swapnareddy says:

    my doubt is i have select some items from the list given with the help of check box .when i chek the items in the list ,the items which have been checked from the list with the help of check box should be displayed on the dat grid in adobe flex.can any one let me know the code for it in adobe flex?
    Thanks in advance

  27. Alex Harui says:

    It should work. You might post what you’ve tried on the forums. You’ll get faster assistance there.

  28. Alex Harui says:

    SmoothScrolling is much harder problem in Halo list if the rows are different heights. Try the Spark List in Flex 4 beta

  29. Alex Harui says:

    Please ask on an Adobe forum. That is not relevant to this topic.

  30. Phil says:

    Cheers for this, its real helpful 🙂

  31. Brian says:

    Has anyone successfully added/fixed the mouse wheel support with this demo? My attempts appear to kill mouse wheel support all together..?

  32. Timo Stamm says:

    Hi there,
    thanks for your extended List. I took the liberty of fixing the MouseWheel support. Here is the function you need to add to your SmoothingList:
    override protected function mouseWheelHandler(event:MouseEvent):void {
    // Scrolldirection and distance calculation
    var scrollAmount:Number = verticalScrollBar.lineScrollSize * event.delta * -1;
    var oldPosition:Number = super.verticalScrollPosition;
    var newPosition:Number = super.verticalScrollPosition + scrollAmount;
    if (newPosition maxVerticalScrollPosition) {
    newPosition = maxVerticalScrollPosition;
    }
    verticalScrollBar.scrollPosition = newPosition;
    var scrollEvent:ScrollEvent = new ScrollEvent(ScrollEvent.SCROLL);
    scrollEvent.detail = (event.delta

  33. romil says:

    You just need to override mouseWheelHandler to fix the mouse wheel issue:
    override protected function mouseWheelHandler (event:MouseEvent) : void
    {
    var delta:Number = Number(event.delta);
    var pos:Number = verticalScrollPosition;
    var newpos:Number = verticalScrollPosition;
    if(delta = maxVerticalScrollPosition) {
    newpos = maxVerticalScrollPosition;
    } else {
    newpos = pos + Math.abs(delta);
    }
    } else {
    if( ((pos – delta)

  34. Matt R. says:

    Alex,
    Fantastic code example to help me understand the scroll handler. I adapted and simplified your example to add smooth horizontal scrolling into a data grid. I am using the DataGrid in a less conventional way for document/report analysis and the normal snap-to-column horizontal scroll was very very frustrating.
    I posted my answer on StackOverflow and cited this blog post, plus added my version of the scrollHandler for horizontal scrolling.
    StackOveflow – Making a Flex DataGrid scroll smoothly…
    Cheers!
    Matt

  35. pradeep says:

    Hi Jayesh,
    Please share the solution for datagrid with image item renderer in datagrid when we scroll the grid.
    Regards,
    Pradeep

  36. Devin says:

    Hi –
    I’m having the same issue as Nate – using SDK 3.5 i’m getting headers jumping around when you scroll up and down – they shouldn’t move at all – any way to fix this?
    Thanks!
    – Devin

  37. kaolin fire says:

    Just to simplify the mouse scroll wheel override (and hopefully fix some html problems in the above posts) ~
    //from comments below post
    override protected function mouseWheelHandler (event:MouseEvent) : void {
    var delta:Number = Number(event.delta);
    if(delta < 0) { // scrolling DOWN
    verticalScrollPosition = Math.min(verticalScrollPosition – delta, maxVerticalScrollPosition);
    } else {
    verticalScrollPosition = Math.max(verticalScrollPosition – delta, 0);
    }
    super.mouseWheelHandler(event);
    }

  38. AnupKumar says:

    i need vertically auto scrolling list contol smoothly
    is it possilble using Flex3?

  39. Alex Harui says:

    You might be able to modify this example to do what you want.

  40. Amit says:

    Hi Alex. I am using TileList (horizontal scrolling) with Thumbnails. I copied your code and modified verticalscroll to horizontalscroll, top to left and moving List to x cordinates instead of y

    listContent.move(viewMetrics.left+ listContent.leftOffset – fraction,listContent.y);

    I am having problem with images not getting updated in scrolling. First time it scrolls fin. After I scroll left, the images on left repeat after say every 4 thumbnails. I thought it is recycling issue. However regular TIlelist does not have such issue. Do you have any idea what might be happening. Or what line in the code to look at.?

    • Alex Harui says:

      No idea. Is 4 the number of visible tiles horizontally? Are the tiles layed out vertically or are you trying to get both a horizontal and vertical scrollbar on the tile list?

  41. Could you do something like wrapping the content in a VBox and have that in the updateDisplayList? I am going to try it. But I know if it was that simple, somebody would have tried it..

    • Alex Harui says:

      Yes you can, but then you no longer have virtual renderers so if you have a lot of rows it will take a lot of memory

  42. Or.. put the Advanced Data Grid in a VBox, but some how put the header on the parent element not inside the Canvas? I am just thinking out loud and writing it down..

  43. and does the spark Datagrid and AdvancedDatagrid fix this? Saw the video and it looks like it might fix this issue.

  44. jogou says:

    Alex:
    I want to scroll the DataGrid smoothly,i tried to make it form the List version,but it to hard to me.could you help me?

    • Alex Harui says:

      Unfortunately, I don’t have time to help you. Try asking for help on the forums. Or wait for Spark DataGrid

  45. Mark says:

    I see above you mention the Spark DG does smooth scrolling so is it safe to assume a Spark List scrolls smoothly also>
    thanks, Mark