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.
Comments
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.
Posted by: Troy Gilbert | March 3, 2008 11:45 AM
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.
Posted by: Luke | March 3, 2008 1:59 PM
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.
Posted by: Josh Santangelo | March 10, 2008 4:48 PM
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
Posted by: Michael | March 18, 2008 1:24 PM
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?
Posted by: Michael | March 19, 2008 4:12 AM
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.
Posted by: Michael | March 25, 2008 2:57 AM
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
Posted by: Al | April 1, 2008 5:25 PM
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.
Posted by: John | April 3, 2008 5:51 PM
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
Posted by: joerg | April 10, 2008 6:11 AM
Thanks, this works great, just what I needed.
Posted by: nemke | April 29, 2008 2:13 AM
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.
Posted by: Nate | May 14, 2008 12:42 AM
Thanks for this. I appreciate it!
Posted by: Brent Lamborn | May 27, 2008 9:13 AM
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.
Posted by: Poesco | May 30, 2008 6:27 AM
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
Posted by: Christian Nunciato | June 17, 2008 3:50 PM
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.
Posted by: David Patrick | July 11, 2008 2:21 PM
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
Posted by: Mario | August 28, 2008 8:35 AM
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.
Posted by: dev | September 8, 2008 2:37 AM
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.
Posted by: Carl | September 25, 2008 3:27 PM
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/
Posted by: Alvaro Carrasco | November 9, 2008 11:20 AM
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.
Posted by: Jayesh Sharma | January 20, 2009 10:14 PM
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
Posted by: Jon | February 13, 2009 2:47 PM
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
Posted by: Lily | April 30, 2009 2:04 PM
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.
Posted by: Sosh | May 2, 2009 3:14 AM