Smooth Scrolling List

| 35 Comments

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

35 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.

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.

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.

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

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?

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.

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

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.

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

Thanks, this works great, just what I needed.

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.

Thanks for this. I appreciate it!

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.

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

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.

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

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.

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.

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/

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.

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

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

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.

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

any idea

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!

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

Cheers for this, its real helpful :)

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

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 newPosition = 0;
} else if (newPosition > maxVerticalScrollPosition) {
newPosition = maxVerticalScrollPosition;
}
verticalScrollBar.scrollPosition = newPosition;

var scrollEvent:ScrollEvent = new ScrollEvent(ScrollEvent.SCROLL);
scrollEvent.detail = (event.delta scrollEvent.direction = ScrollEventDirection.VERTICAL;
scrollEvent.position = newPosition;
scrollEvent.delta = newPosition - oldPosition;

verticalScrollBar.dispatchEvent(scrollEvent);
}

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 delta = Math.abs(delta);
if(pos + delta>= maxVerticalScrollPosition) {
newpos = maxVerticalScrollPosition;
} else {
newpos = pos + Math.abs(delta);
}
} else {
if( ((pos - delta) newpos = 0;
} else {
newpos = pos - delta;
}
}

verticalScrollPosition = newpos;

super.mouseWheelHandler(event);
}

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

Hi Jayesh,

Please share the solution for datagrid with image item renderer in datagrid when we scroll the grid.

Regards,
Pradeep

Leave a comment


Type the characters you see in the picture above.

About this Entry

This page contains a single entry by Alex Harui published on March 2, 2008 11:05 PM.

CheckBox selection in DataGrid and List was the previous entry in this blog.

DataGrid Double-Click To Edit is the next entry in this blog.

Find recent content on the main index or look in the archives to find all content.