19 Replies Latest reply on Oct 9, 2009 3:02 PM by Shongrunden

    Skinning Scroll Bars

    bdun42

      All - I'm tryingto skin the spark scrollbar (on a list) to remove the thumb and track and to move the scroll increment/decrement buttons above and below the content. Remvoing the thumb and track are easy enough (I simply copied VScrollBarSkin and removed the track and thumb SkinParts).  I'm stuck on the moving of the increment/decrement buttons b/c according to the documentation in Scroller the layout cannot be changed:

       

      The Scroller skin layout cannot be changed. It is unconditionally set to a
      private layout implementation that handles the scroll policies.  Scroller skins
      can only provide replacement scrollbars.  To gain more control over the layout
      of a viewport and its scrollbars, instead of using Scroller, just add them
      to a Group and use the scrollbar viewport property

      to link them together.

       

      So, it seems that I will need to use this Group and viewport idea. Am I going about this the correct way? Anybody have an example of doing this?

       

      Thanks!

      Bryan

        • 1. Re: Skinning Scroll Bars
          David_F57 Level 5

          Heres a quick and "dirty" way to do what you want -

           

          <s:Button label="up" top="-25" click="hostComponent.layout.verticalScrollPosition -= 25"/>

          <s:Button label="down" top="{hostComponent.height+5}" click="hostComponent.layout.verticalScrollPosition += 25"/>

           

              <!--- The Scroller component to add scroll bars to the list. -->

              <s:Scroller left="0" top="0" right="0" bottom="0" id="scroller" minViewportInset="1" focusEnabled="false"

          verticalScrollPolicy="off" horizontalScrollPolicy="off">

                  <!--- The container for the data items. -->

                  <s:DataGroup id="dataGroup" itemRenderer="spark.skins.spark.DefaultItemRenderer">

                      <s:layout>

                          <s:VerticalLayout gap="0" horizontalAlign="contentJustify" />

                      </s:layout>

                  </s:DataGroup>

              </s:Scroller>

          Notice what I have done- switched scrollpolicy off in the scroller, placed a button above and below the list and set the scrollposition in the button click, very simple change to a list skin and it works, the buttons could obviously be what ever you want, graphics a rollover area that uses an animated effect to scroll your listbox.
          David.

          • 2. Re: Skinning Scroll Bars
            HansMuller Level 1

            It sounds like you want a List with no scrollbars and step up/down buttons above and below the List's DataGroup.  If that's what you want, you could create a copy of spark.skins.sparkListSkin without a Scroller - the Scroller is an optional skin part - and the DataGroup wrapped in a VGroup along  with the up/down buttons.  You'd have to set clipAndEnableScrolling=true on the DataGroup, usually the Scroller does that.  

             

            • 3. Re: Skinning Scroll Bars
              David_F57 Level 5

              Hi Hans,

               

              If someone is not familiar with the interaction of scroller and datagroup simply removing the scroller could cause some issues, switching the scroll policy off is a less intrusive change to the listbox behaviour(basically all that does is hide the slider graphics and prevent the viewport resizing). This way the changes to the skin is minimal and behaviour will not be affected. The up/down action can be controlled through the existing scroller functions. As the example I showed earlier 2 lines of code added to the skin and 2 properties set on the scroller and the desired effect is achieved.

               

              Just a quick note, with FB Beta 2 if you write click on the listbox in design view there is a menu item that will create a copy of the listskin in your project, this is the skin you would then use to make your changes.

               

              David

              • 4. Re: Skinning Scroll Bars
                bdun42 Level 1

                Hans - You are correct, I am looking for up/down buttons at the top/bottom of the list to perform the scroller. I think removing scroller is what I'm looking for (as the API docs say). I've done what you said but nothing is being clipped, the data items are going outside the list. Can you expand on your thought some more? Or possibly provide an example?

                 

                Thanks,

                Bryan

                • 5. Re: Skinning Scroll Bars
                  David_F57 Level 5

                  this is using the skin method

                   

                  http://gumbo.flashhub.net/scroller/

                   

                  right click on swf to get the source

                   

                   

                  David.

                  • 6. Re: Skinning Scroll Bars
                    tstatler

                    I hit the same problem. Since the DataGroup in the skin doesn't have an explicit height/width set, clipAndEnableScrolling doesn't have a frame to clip to. The solution is to set the DataGroup's height/width to the host component's height/width.

                     

                    <DataGroup ... height="{hostComponent.height}" width="{hostComponent.width}" ...  />


                    Tim

                    • 7. Re: Skinning Scroll Bars
                      Shongrunden Adobe Employee

                      Attached is a sample app that has a DataGroup that you can scroll up/down by one item at a time without scrollbars.  I thought I would post it here in case it helps at all.

                      • 8. Re: Skinning Scroll Bars
                        bdun42 Level 1

                        Shongrunden - Did you forget to attach?

                        • 9. Re: Skinning Scroll Bars
                          Shongrunden Adobe Employee

                          The post didn't go through completely, hopefully this file is attached this time.

                          • 10. Re: Skinning Scroll Bars
                            Shongrunden Adobe Employee

                            Forum fail.  I'll just paste here instead:

                             

                            <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
                                           xmlns:s="library://ns.adobe.com/flex/spark">
                               
                                <fx:Script>
                                    <![CDATA[
                                        import spark.layouts.VerticalLayout;
                                        import spark.core.NavigationUnit;

                             

                                        private function scroll(direction:String):void {
                                            var layout:VerticalLayout = group1.layout as VerticalLayout;
                                           
                                            if (direction == "down")
                                                group1.verticalScrollPosition += layout.getVerticalScrollPositionDelta(NavigationUnit.DOWN);

                             

                                            if (direction == "up")
                                                group1.verticalScrollPosition += layout.getVerticalScrollPositionDelta(NavigationUnit.UP);
                                           
                                        }
                                    ]]>
                                </fx:Script>
                               
                                <s:VGroup>
                                       
                                    <s:DataGroup id="group1" itemRenderer="spark.skins.spark.DefaultItemRenderer" clipAndEnableScrolling="true">
                                        <s:layout>
                                            <s:VerticalLayout useVirtualLayout="true" requestedRowCount="1" gap="0" />
                                        </s:layout>
                                        <s:dataProvider>
                                            <s:ArrayCollection>
                                                <fx:String>item 0</fx:String>
                                                <fx:String>item 1</fx:String>
                                                <fx:String>item 2</fx:String>
                                                <fx:String>item 3</fx:String>
                                                <fx:String>item 4</fx:String>
                                                <fx:String>item 5</fx:String>
                                                <fx:String>item 6</fx:String>
                                                <fx:String>item 7</fx:String>
                                                <fx:String>item 8</fx:String>
                                                <fx:String>item 9</fx:String>
                                            </s:ArrayCollection>
                                        </s:dataProvider>
                                    </s:DataGroup>
                                   
                                    <s:Button label="scroll down" click="scroll('down')" />
                                    <s:Button label="scroll up" click="scroll('up')" />
                               
                                </s:VGroup>   
                               
                            </s:Application>

                            • 11. Re: Skinning Scroll Bars
                              bdun42 Level 1

                              All of these suggestions seem like good ways to work around the fact that we cannot change the layout of the spark scroll bar. The problem I see with all of them is that once you break out of the framework you have to handle everything on your own (e.g when the buttons show up, autoRepeat, etc).

                               

                              I feel that it should be much easier to change the default layout of the scroll bar, again that's really all I'm trying to do here. Instead of having the normal Up/Down with track and thumb, I want my up down button to span the width of the list component (preferably still inside the confines of the list).

                               

                              Thoughts?

                              • 12. Re: Skinning Scroll Bars
                                David_F57 Level 5

                                The problem is anyway you do it there is going to be coding required, if you modified the scrollbar (nothumb, no track) you would then need to 'stretch' it over the list area the next thing you would have to do is change the viewport otherwise the buttons would cover the first and last row of the list and then probably skin the buttons cause they would probably look a little weird.. Flex 4 is great because you have the ability to achieve effects that required way to much work in flex 3. skinning a listbox and adding a few one line functions to emulate what a scroller normally does is a small price to pay for what you can accomplish with the current sdk.

                                 

                                David

                                • 13. Re: Skinning Scroll Bars
                                  bdun42 Level 1

                                  I agree that I should have to skin the buttons and maybe modify the measurements of the viewport to take into account that the buttons are on top of the list (instead of to the right). My point was that in the Spark architecture the responsibility of behaviour and look/feel are separated (big plus), so it seems to me that limiting the way the scroll bar is layed out goes against this architecture.  Layout should be nothing more than a decoration on top of the functionality of the scrollbar.  That is, if I take a way the thumb from the skin that should in no way effect the function of scrolling (I no longer have the ability to do a drag scroll on the thumb but the functionality still exists in scroller).

                                   

                                  In other words, I expect to have to write code to get this to do what I want, but I would only expect to write layout and skinning code.

                                  • 14. Re: Skinning Scroll Bars
                                    Shongrunden Adobe Employee

                                    I quickly wrote up a custom List skin and custom VScrollBar skin to show that only a few lines of MXML can get what (I think) you are looking for pretty easily.  (This is rough so the borders might not be properly accounted for yet, but you get the idea).

                                     

                                    Does this give you some guidance on what you want to do?

                                    • 15. Re: Skinning Scroll Bars
                                      Shongrunden Adobe Employee

                                      The forums keep eating my messages today, but in addition to my last post:

                                       

                                      This was roughly my approach in creating that sample:

                                       

                                      1. Copied the default ListSkin.mxml into CustomListSkin.mxml
                                      2. Remove the Scroller (apply its top/left/right/clipAndEnableScrolling to the DataGroup below it)
                                      3. Remove the references to the scroller in the script block at the top
                                      4. Add a VScrollBar, position it at 100% width and height
                                      5. Increase top/bottom on the DataGroup to allow some space for the buttons
                                      5. Copied the default VScrollBarSkin.mxml into CustomVScrollBarSkin.mxml
                                      6. Tweak the VScrollBar skin to get rid of the track and the thumb and make the buttons 100% width

                                      1 person found this helpful
                                      • 16. Re: Skinning Scroll Bars
                                        mewk Level 3

                                        my thoughts are that you should not be skinning the scrollbar at all. try this (or better yet import the .fxp file)

                                         

                                        • 17. Re: Skinning Scroll Bars
                                          mewk Level 3

                                          argg, i'm having trouble posting too. will try again

                                           

                                           

                                          <?xml version="1.0" encoding="utf-8"?>
                                          <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 
                                                            xmlns:s="library://ns.adobe.com/flex/spark" 
                                                            xmlns:mx="library://ns.adobe.com/flex/halo"
                                                            creationComplete="init()">
                                               
                                               <fx:Script>
                                                    <![CDATA[
                                                         import mx.collections.ArrayCollection;
                                                         
                                                         import spark.components.Scroller;
                                                         
                                                         [Bindable] public var myImageCollection:ArrayCollection = 
                                                              new ArrayCollection([
                                                                   'assets/star.png',
                                                                   'assets/star2.png', 
                                                                   'assets/star.png', 
                                                                   'assets/star2.png', 
                                                                   'assets/star.png', 
                                                                   'assets/star2.png',
                                                                   'assets/star.png',
                                                                   'assets/star2.png', 
                                                                   'assets/star.png', 
                                                                   'assets/star2.png', 
                                                                   'assets/star.png', 
                                                                   'assets/star2.png']);
                                                         
                                                         [Bindable] private var myScroller:Scroller;
                                                         
                                                         private function init():void {
                                                              myScroller = myList.scroller;
                                                              myScroller.setStyle("verticalScrollPolicy", 'off');
                                                              myScroller.setStyle("horizontalScrollPolicy", 'off');
                                                         }
                                                    ]]>
                                               </fx:Script>
                                               
                                               <fx:Declarations>          
                                                    <s:Animate id="scrollRight" target="{myScroller.horizontalScrollBar}">
                                                         <s:SimpleMotionPath valueBy="120" property="value"/>
                                                    </s:Animate>
                                                    <s:Animate id="scrollLeft" target="{myScroller.horizontalScrollBar}">
                                                         <s:SimpleMotionPath valueBy="-120" property="value"/>
                                                    </s:Animate>
                                               </fx:Declarations>
                                               
                                               
                                               
                                               <s:Group width="200" height="100" horizontalCenter="0" verticalCenter="0">
                                                    <s:List id="myList"
                                                              width="200" height="100" 
                                                              horizontalCenter="0" verticalCenter="0"
                                                              itemRenderer="renderers.myItemRendererSmoother"
                                                              dataProvider="{myImageCollection}">
                                                         <s:layout>
                                                              <s:HorizontalLayout />
                                                         </s:layout>
                                                    </s:List>
                                                    <s:Group id="leftScroller" left="0" width="20" height="100%" color="black" alpha="0.1"
                                                               click="scrollLeft.end();scrollLeft.play()"
                                                               rollOver="leftScroller.alpha=0.3"
                                                               rollOut="leftScroller.alpha=0.1">
                                                         <s:Rect width="100%" height="100%">
                                                              <s:fill>
                                                                   <s:SolidColor color="black" />
                                                              </s:fill>
                                                         </s:Rect>
                                                    </s:Group>
                                                    <s:Group id="rightScroller" right="0" width="20" height="100%" color="black" alpha="0.1"
                                                               click="scrollRight.end();scrollRight.play()"
                                                               rollOver="leftScroller.alpha=0.3"
                                                               rollOut="leftScroller.alpha=0.1">
                                                         <s:Rect width="100%" height="100%">
                                                              <s:fill>
                                                                   <s:SolidColor color="black" />
                                                              </s:fill>
                                                         </s:Rect>
                                                    </s:Group>
                                               </s:Group>
                                          </s:Application>
                                          

                                           

                                           

                                          renderers/myItemRendererSmoother

                                           

                                          <s:ItemRenderer
                                               xmlns:fx="http://ns.adobe.com/mxml/2009"
                                               xmlns:s="library://ns.adobe.com/flex/spark"
                                               xmlns:mx="library://ns.adobe.com/flex/halo"
                                               minHeight="50">
                                               
                                               <s:states>
                                                    <s:State name="normal" />
                                                    <s:State name="hovered" />
                                                    <s:State name="selected" />
                                               </s:states>
                                               
                                               <mx:Image source="{data}" />
                                                         
                                          </s:ItemRenderer>
                                          

                                           

                                           

                                           

                                          - e

                                          1 person found this helpful
                                          • 18. Re: Skinning Scroll Bars
                                            bdun42 Level 1

                                            mewk and shongrunden - thanks for the examples.

                                             

                                            shongrunden  - that is exactly what I was looking for, and the way I was trying to implement it. I think what was throwing me was setting the viewport to the datagroup.

                                             

                                            Thanks again to all!

                                            • 19. Re: Skinning Scroll Bars
                                              Shongrunden Adobe Employee

                                              mewk - nice, I like your use of effects while changing scroll position

                                               

                                              I tweaked the example I posted earlier to fix the border issue and added the code to my blog:

                                              http://flexponential.com/2009/10/09/changing-the-position-of-the-scroll-bars-in-a-spark-li st/