26

I'm setting selected element in s:List component with Actionscript, it works, but List doesn't scroll to selected item -- need to scroll with scrollbar or mouse. Is it possible to auto-scroll to selected item ? Thanks !

ketan
  • 19,129
  • 42
  • 60
  • 98
Rodion Bykov
  • 614
  • 1
  • 7
  • 14

12 Answers12

23

Try the s:List method ensureIndexIsVisible(index:int):void.

merv
  • 67,214
  • 13
  • 180
  • 245
an0nym0usc0ward
  • 1,207
  • 8
  • 8
  • Thanks, but it seems working in latest Flex 4 SDK builds only (Flex Builder 4 Beta 2). I realized I work with one of old builds that has no this method yet. – Rodion Bykov Nov 13 '09 at 22:17
  • 1
    this also only scrolls so that the top of the item is visible, if the item is tall this does not scroll to the bottom – JTtheGeek Dec 01 '10 at 23:48
  • @JTtheGeek Yes, in Spark List 4.6 it seems you must click twice to scroll to bottom. – Nemi Jan 17 '14 at 14:38
6

For Spark:

list.ensureIndexIsVisible(index);

Yozef
  • 829
  • 11
  • 27
4
//try this
this.callLater(updateIndex);//where you want to set the selectedIndex

private function updateIndex():void
{
    list.selectedIndex = newIndex;
    list.ensureIndexIsVisible(newIndex);
}
  • 1
    Shorter version: `callLater(list.ensureIndexIsVisible, [list.selectedIndex])` but still not the best solution - throws index out of range errors sometimes – Alexander Farber Nov 03 '12 at 10:36
4

This function will scroll to the top of the list in Flex 4+. It takes in account the height of the item, so it will work for lists with different items with different height.

private function scrollToIndex(list:List,index:int):void
{
    if (!list.layout)
        return;

    var dataGroup:DataGroup = list.dataGroup;

    var spDelta:Point = dataGroup.layout.getScrollPositionDeltaToElement(index);

    if (spDelta)
    {
        dataGroup.horizontalScrollPosition += spDelta.x;
        //move it to the top if the list has enough items
        if(spDelta.y > 0)
        {
            var maxVSP:Number = dataGroup.contentHeight - dataGroup.height;
            var itemBounds:Rectangle = list.layout.getElementBounds(index);
            var newHeight:Number = dataGroup.verticalScrollPosition + spDelta.y 
            + dataGroup.height - itemBounds.height;
            dataGroup.verticalScrollPosition = Math.min(maxVSP, newHeight);
        }
        else
        {
            dataGroup.verticalScrollPosition += spDelta.y;

        }
    }
}
Heitara
  • 452
  • 5
  • 10
3

In flex-3 there is a scrollToIndex method and hence you can call

list.scrollToIndex(list.selectedIndex);

I believe this should work in flex-4 too.

Amarghosh
  • 58,710
  • 11
  • 92
  • 121
  • Unfortunately, no. There's no such method in Spark List, but it's there for Halo List component. Flex 4 is evolving and still in Beta, hope this issue will be resolved. – Rodion Bykov Oct 29 '09 at 11:23
3

This worked for me. had to use the callLater.

list.selectedItem = "MyTestItem"; //or list.selectedIndex = 10;
this.callLater(updateIndex); //dispatch an update to list

private function updateIndex():void {
    list.ensureIndexIsVisible(list.selectedIndex);
}
JJ_Coder4Hire
  • 4,706
  • 1
  • 37
  • 25
2

You'll probably want to access the List's scroller directly and do something like:

list.scroller.scrollRect.y = list.itemRenderer.height * index;

merv
  • 67,214
  • 13
  • 180
  • 245
shi11i
  • 1,528
  • 13
  • 16
  • I found that you can't change the value inside scrollRect directly, instead you need to update scrollRect with a new rectangle? like [this](http://www.actionscript.org/forums/showthread.php3?t=190795) – eldamar Jul 06 '11 at 12:09
2

I saw this basic idea here... http://arthurnn.com/blog/2011/01/12/coverflow-layout-for-flex-4/

public function scrollGroup( n : int ) : void
{
    var scrollPoint : Point = theList.layout.getScrollPositionDeltaToElement( n );
    var duration : Number = ( Math.max( scrollPoint.x, theList.layout.target.horizontalScrollPosition ) - Math.min( scrollPoint.x, theList.layout.target.horizontalScrollPosition )) * .01;
    Tweener.addTween(theList.layout,{ horizontalScrollPosition: scrollPoint.x , time:duration});
}
protected function theList_caretChangeHandler(event:IndexChangeEvent):void
{
    scrollGroup( event.newIndex );
    event.target.invalidateDisplayList();
}
1

You can multiply the height of an element by its index and pass this value to:

yourListID.scroller.viewport.verticalScrollPosition
merv
  • 67,214
  • 13
  • 180
  • 245
1

It is a bug - you can see the demonstration and a workaround at the https://issues.apache.org/jira/browse/FLEX-33660

Alexander Farber
  • 21,519
  • 75
  • 241
  • 416
1

This custom List component extension worked for me:

<s:List
    xmlns:fx="http://ns.adobe.com/mxml/2009"
    xmlns:s="library://ns.adobe.com/flex/spark"
    valueCommit="callLater(ensureIndexIsVisible, [selectedIndex])">
</s:List>
0

I recently accomplished this in one of my projects by having a defined size for my items in the group..

<s:Scroller x="940" y="0" maxHeight="465" maxWidth="940" horizontalScrollPolicy="off" verticalScrollPolicy="off">
  <s:HGroup  id="tutPane" columnWidth="940" variableColumnWidth="false" gap="0" x="0" y="0">
  </s:HGroup>
</s:Scroller>

Following this my button controls for manipulation worked by incrementing a private "targetindex" variable, then I called a checkAnimation function, which used the Animate class, in combo with a SimpleMotionPath and a comparison between tutpane.firstIndexInView and target index. This modified the "horizontalScrollPosition" of the group.

This allowed separate controls to essentially act as a scroll bar, but I had the requirement of sliding the control to view the selected item.. I believe this technique could work for automated selection of items as well

Method
  • 353
  • 3
  • 10