Scrolling List Control with Tweener

I was on a simple little side task last week, to create a scrolling effect using the Flex control and also remove the default scroll bars. I didn’t want to do the usual trick, scrolling a HBox with items added to it using a repeater, or whatever. I wanted to animate the scrolling that occurs within an actual List control but give it a little easing effect. The call went out to Twitter for suggestions, and within minutes Jesse Warden responded with with “use the tween class dude” and also my friend Jerry Don reminded me of a new smooth scrolling List created by Alex Harui. This helped to point me in the right direction.

Scrollbars and Mouse Wheel

The first objective was to remove the default List scroll bar because I wanted to use buttons to scroll the list from the top to bottom and vice versa with just one click of a button. Ok, no problem, verticalScrollPolicy=”off” just hides the scroll bar, however it also removes the ability to scroll the list with the mouse wheel. Now I had to hack into the List control to add this functionality back. This part was not too hard, I found a good code example, though it was in German, and repurposed it for my needs.

 /**
 * Override the mouseWheelHandler so if the verticalScrollPolicy is "off"
 * we use the MouseEvent.delta value to manually update the List control
 * scroll position when there is no ScrollBar.
 *
 * */
 override protected function mouseWheelHandler(event:MouseEvent):void
 {
 if(verticalScrollPolicy == ScrollPolicy.OFF && maxVerticalScrollPosition != 0){
 var len:Number = dataProvider.length;
 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) <= 0 ) || pos == 0){
 newpos = 0;
 } else {
 newpos = pos - delta;
 }
 }

verticalScrollPosition = newpos;
 }

super.mouseWheelHandler(event);
 }
 

Tween List

I then through on some buttons that would scroll the list from the current position to either the start or the end. Now began the work with to add the easing function so the list would scroll fast at the start of the scroll and then slow down just before reaching the end or beginning of the list, depending on which way you want to scroll. I started with the built in mx.effects.Tween class which really proved to be the least effective. One problem with the List control is that its not incremental, it scrolls by row, making for a choppy scroll experience. So instead of being able to scroll in smaller increments, you have to scroll by whole numbers, which doesn’t allow enough runway to make the list easing effect noticeable. Using the regular Tween and a mx.effects.easing.Circle effect might look something like this:

 private function tweenDown():void
 {
 var pos:Number = list.verticalScrollPosition;
 var end:Number = list.maxVerticalScrollPosition;
 var tween:Tween = new Tween(this, pos, end, 1400, 10, tweenUpdateHandler, tweenEndHandler);
 tween.easingFunction = Circular.easeOut;
 }

private function tweenUpdateHandler(value:String):void
 {
 list.verticalScrollPosition = Math.round(Number(value));
 }

private function tweenEndHandler(value:String):void
 {
 trace('tween end value: ' + value);
 }
 

Notice that you need to round the value returned in the tweenUpdateFunction, if you don’t, then your list will get hosed because the list can’t handle values like

tween value: 0.03486542280255378
tween value: 0.01960467102681207
tween value: 0.01022360862317484
tween value: 0.0032527319110684516
tween value: 0.0001680006720050642

Smooth Scrolling List

This is where I thought Alex’s smooth scrolling list would come into play because it allows for or smooth scrolling by increments. In theory, you shouldn’t have to round up the number, you should be able to apply the values directly to the verticalScrollPosition property of the list. Alex’s prototype is suppose to allow this, which it does to some extent. The prototype list can handle it when you scroll down, but not back up to the top, it breaks down. So this doesn’t really solve the problem of smoothly scrolling the list when updating the verticalScrollPosition with a Tween effect. However, his list does have some value as it allows for smooth scrolling when you use the mouse wheel.

Example

Below is the example and code. Don’t expect the mouse wheel to work if you are on Mac OS X, because its not supported in the Flash Player. If you are interested in a work around for the mouse wheel issue, check out this the piexelbreaker.com post for a workaround. Of course the mouse wheel works fine in Adobe AIR. Also, the longer the list of data, the better the animation effect because there is more data to show the full effect. The effect could still be improved, but until Adobe releases a new set of List components that scroll properly, this is as good as it may get. Let me know if anyone has any other suggestions.

Download the ScrollTweenEffect.zip file for the source code.

UPDATE

A friend suggested I look at the Flex mx.effects.AnimateProperty to animate the scrollbar for the List. He pointed to me to a blog post by Thomas Decaux. I will try to work up an example using his approach to compare the two.

– Mister

5 Comments

Comments are closed.