How do I hide a vertical scrollbar (without disabling it)? - apache-flex

I have a list but want to hide the scrollbar but still keep the functionality. If I put verticalScrollPolicy="off", this disables scrolling via the mousewheel on windows (100% of my users use windows). How can I hide the scrollbar visually but keep the ability to scroll via the keyboard as well as the mousewheel?
<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:mx="library://ns.adobe.com/flex/mx"
xmlns:s="library://ns.adobe.com/flex/spark" height="100%" width="100%">
<s:Group>
<s:List id="listy" width="50%" height="100">
<mx:ArrayCollection>
<fx:String>Flash</fx:String>
<fx:String>Director</fx:String>
<fx:String>Dreamweaver</fx:String>
<fx:String>ColdFusion</fx:String>
<fx:String>Flash</fx:String>
<fx:String>Director</fx:String>
<fx:String>Dreamweaver</fx:String>
<fx:String>ColdFusion</fx:String>
<fx:String>Flash</fx:String>
<fx:String>Director</fx:String>
<fx:String>Dreamweaver</fx:String>
<fx:String>ColdFusion</fx:String>
</mx:ArrayCollection>
</s:List>
</s:Group>

I believe the way you'd want to do it to set a custom skin for the List, which then sets a custom skin for the Scroller component within it. In the Scroller skin, you could set the scrollbar as visible=false.

Just type:
<s:Scroller id="myScroller" verticalScrollBar="{new VScrollBar()}">
This code solve my problem=)

Ive been looking for a solution for this question , and I think it's a problem many people ancounter , so I decided to answer this question although its quite old.
The solution for your problem is real simple. You simply make a custom skin for the scroller and inside the scroller simply set the vertical scroller "alpha" property set to zero
<s:VScrollBar id="verticalScrollBar" visible="false" alpha="0"/>
Hope this will help someone

You could use verticalScrollPolicy="off" and create a listener for the mouse scroll event to trigger the scrolling when the mouse is hovering the list.

In order to hide scrollbars but still have access to scrolling functionality, you need to create a custom skin and a css style.
Create a custom skin for the VScrollBar with the following settings:
Host Component: spark.components.VScrollBar
Select "Create as copy of:", and select "spark.skins.spark.VScrollBarSkin"
Edit the "SparkSkin" tag in your custom skin by adding "minWidth="0" minHeight="0" width="0" height="0" alpha="0" visible="false" contentBackgroundAlpha="0""
Original
<s:SparkSkin xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:fb="http://ns.adobe.com/flashbuilder/2009" minWidth="15" minHeight="35"
alpha.disabled="0.5" alpha.inactive="0.5" >
Customized
<s:SparkSkin xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:fb="http://ns.adobe.com/flashbuilder/2009" minWidth="0" minHeight="0" width="0" height="0" alpha="0" visible="false" contentBackgroundAlpha="0">
Then edit your custom skin by adding "alpha="0" visible="false" width="0"" to each of the elements:
Original:
<s:Button id="track" top="16" bottom="15" height="54"
focusEnabled="false" tabEnabled="false"
skinClass="spark.skins.spark.VScrollBarTrackSkin" />
<s:Button id="thumb"
focusEnabled="false" visible.inactive="false" tabEnabled="false"
skinClass="spark.skins.spark.VScrollBarThumbSkin" />
<s:Button id="decrementButton" top="0" enabled.inactive="false"
focusEnabled="false" tabEnabled="false"
skinClass="spark.skins.spark.ScrollBarUpButtonSkin" />
<s:Button id="incrementButton" bottom="0" enabled.inactive="false"
focusEnabled="false" tabEnabled="false"
skinClass="spark.skins.spark.ScrollBarDownButtonSkin" />
Customized:
<s:Button id="track" top="16" bottom="15" height="54" alpha="0" visible="false" width="0"
focusEnabled="false" tabEnabled="false"
skinClass="spark.skins.spark.VScrollBarTrackSkin" />
<s:Button id="thumb" alpha="0" visible="false" width="0"
focusEnabled="false" visible.inactive="false" tabEnabled="false"
skinClass="spark.skins.spark.VScrollBarThumbSkin" />
<s:Button id="decrementButton" top="0" enabled.inactive="false" alpha="0" visible="false" width="0"
focusEnabled="false" tabEnabled="false"
skinClass="spark.skins.spark.ScrollBarUpButtonSkin" />
<s:Button id="incrementButton" bottom="0" enabled.inactive="false" alpha="0" visible="false" width="0"
focusEnabled="false" tabEnabled="false"
skinClass="spark.skins.spark.ScrollBarDownButtonSkin" />
Add a style to your css (change "assets.skins" to the location of your skin file in your project):
s|List s|VScrollBar {
skinClass: ClassReference("assets.skins.VerticalScrollBarHidden");
}
This style will only apply to List components, so the scroll bar will still be visible for other components. If you want to remove scrollbars altogether, remove "s|List" from the style definition.
Finally add the stylesheet to your application mxml component (replace "assets/css/Styles.css" with the location of your stylesheet):
<fx:Style source="assets/css/Styles.css"/>

Related

How do I get my flex spark skin to center vertically?

I've created a skin that allows me to have two labels on a spark button, but the button text won't center vertically. It stays at the top of the button no matter what settings I give it. The icon in the skin DOES however, center vertically.
This is the skin:
<s:SparkButtonSkin xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:fb="http://ns.adobe.com/flashbuilder/2009"
minWidth="82" minHeight="82"
alpha.disabled="0.5" initialize="autoIconManagement=false">
<fx:Metadata>[HostComponent("com.XXXX.components.TwoLineButton")]</fx:Metadata>
<!-- states -->
<s:states>
<s:State name="up" />
<s:State name="over" />
<s:State name="down" />
<s:State name="disabled" />
</s:states>
<s:Image source="{getStyle('upSkin')}"
source.over="{getStyle('overSkin')}"
source.down="{getStyle('downSkin')}"
source.disabled="{getStyle('disabledSkin')}"
width="100%" height="100%"
/>
<s:HGroup verticalAlign="middle" height="100%" width="100%"
paddingLeft="{getStyle('paddingLeft')}"
paddingRight="{getStyle('paddingRight')}"
paddingTop="{getStyle('paddingTop')}"
paddingBottom="{getStyle('paddingBottom')}"
gap="{getStyle('horizontalGap')}"
verticalCenter="0">
<s:BitmapImage id="iconDisplay" includeInLayout="{iconDisplay.source}"/>
<s:VGroup gap="{getStyle('verticalGap')}" height="100%" width="100%">
<s:Label id="labelDisplay"
textAlign="center"
width="100%"
maxDisplayedLines="1"
horizontalCenter="0" verticalCenter="1" verticalAlign="middle"
left="10" right="10" top="2" bottom="2">
</s:Label>
<s:Label id="bottomLabelDisplay"
textAlign="center"
width="100%"
maxDisplayedLines="1"
horizontalCenter="0" verticalCenter="1" verticalAlign="middle"
left="10" right="10" top="2" bottom="2">
</s:Label>
</s:VGroup>
</s:HGroup>
This is the code I'm calling it with:
<components:TwoLineButton
width="308"
label="TopLabel"
bottomLabel="Bottom label"
click="handleButtonClick(event)"
/>
I've tried making the HGroup use a hardcoded height value, and that doesn't work either.
Thanks in advance.
You cannot use absolute constraints like 'x', 'y', 'left', 'right', 'top', 'bottom', 'horizontalCenter', 'verticalCenter', ... inside a relative layout like VerticalLayout (VGroup is just a Group with a VerticalLayout). This makes sense since you can't position something both relatively and absolutely. In this case the layout of the container takes precedence over whatever constraints you put on the child component. This means you can simply remove any of these constraints you have there: they simply don't have any effect.
Also 'verticalAlign' is a style you apply to a container, but it tells the container how to layout its children. You've assigned it to the Labels, so you're saying "lay out the text component inside the Label in the middle of the Label component" and not "layout the Label component in the middle of the VGroup". So this one is also redundant.
Something like the following should fix your issue:
<s:VGroup height="200">
<s:Label text="A" height="50%" verticalAlign="middle" />
<s:Label text="B" height="50%" verticalAlign="middle" />
</s:VGroup>
or if you want both Labels grouped together in the middle of the VGroup (it's not apparent from the description which one of both you want):
<s:VGroup height="200" verticalAlign="middle">
<s:Label text="A" />
<s:Label text="B" />
</s:VGroup>
The HGroup in your skin should look something like this:
<s:HGroup verticalAlign="middle" height="100%" width="100%"
paddingLeft="{getStyle('paddingLeft')}"
paddingRight="{getStyle('paddingRight')}"
paddingTop="{getStyle('paddingTop')}"
paddingBottom="{getStyle('paddingBottom')}"
gap="{getStyle('horizontalGap')}" >
<s:BitmapImage id="iconDisplay" includeInLayout="{iconDisplay.source}"/>
<s:VGroup gap="{getStyle('verticalGap')}" width="100%" verticalAlign="middle" >
<!-- not sure if you need 100% width here -->
<s:Label id="labelDisplay"
textAlign="center"
width="100%"
maxDisplayedLines="1">
</s:Label>
<s:Label id="bottomLabelDisplay"
textAlign="center"
width="100%"
maxDisplayedLines="1">
</s:Label>
</s:VGroup>
</s:HGroup>
Your labels are in a VGroup so attributes like verticalCenter, horizontalCenter, top, left, etc. do not apply. These attributes only work in BasicLayout (absolutely positioned layouts).
I also removed the 100% height on the VGroup that contained the labels. This means that group of labels will only be as tall as necessary (so now we can actually center it).
Finally, added verticalAlign="middle" to the VGroup. Since the parent of this group is an HGroup, the VGroup should be positioned horizontally next to the BitmapImage if present, and vertically aligned in the middle.

set height of button in spark ButtonBar flex4

i have the following code:
<s:ButtonBar id="tabs" y="15" left="0" height="31"
change="VideosMenuBar_changeHandler(event)" requireSelection="true">
<s:layout>
<s:HorizontalLayout gap="1" columnWidth="180" variableColumnWidth="false"
/>
</s:layout>
<s:ArrayCollection>
<fx:String>Latest Videos</fx:String>
<fx:String>Last Week Videos</fx:String>
<fx:String>Last Month Videos</fx:String>
</s:ArrayCollection>
</s:ButtonBar>
how can i change the height of the buttons in this buttonbar?? is it possible without extra skin class??
i solved the problem with the answer of Maxim Kachurovskiy given above by putting
<s:HorizontalLayout verticalAlign="justify" .../>

Adding background image to mx component while using flex 4

Again, a theming question. Because the project I'm working on requires older libraries that extend mx components (such as TitleWindow and TabNavigator), I can't use what I know about Spark skinning directly. However, since the project is being programmed using the default Spark theme (with my modifications on top) rather than the Halo theme, I apparently don't have access to the styles I need (namely backgroundImage and contentBackgroundImage which apparently require Halo to be active). Simply setting Halo to be the theme will break other things, not the least of which my own theme. Plans are in the works to replace the older libraries or at least patch them better to Flex 4, but as of right now, I need a way to style/skin these components without modifying them directly.
It would be ridiculous to be unable to add a background image to a TitleWindow's content area! I've searched the internet high and low all day and tried countless variations of styles, skins, selectors, and combinations thereof with no luck. Doesn't anyone know how to add a background image to the content of a mx TitleWindow while using the Flex 4.1 sdk?!
Actually, it's not the only way, it's -as you've mentioned- the hardcoded way: sorry about that.
You can also skin your TitleWindow component to accept background images.
To create the appropriate skin with all the necessary states, you can copy the base skin: spark.skins.spark.TitleWindowSkin as MyTitleWindowSkin, and add some customization to it:
In the MetaData tag you should enter the name of your custom TitleWindow class:
<fx:Metadata>
<![CDATA[
[HostComponent("my.package.CustomTitleWindow")]
]]>
</fx:Metadata>
To accept backgroundImage,
you should declare a variable:
[Bindable] private var
backgroundImage:*;
override the
updateDisplayList(unscaledWidth,
unscaledHeight) method, and inside
of it initialize this member:
backgroundImage =
getStyle("backgroundImage");
in the <!-- layer 2: background fill
--> section, after the solid-color-fill (<s:Rect
id="background"...), you should put
the following snippet:
<s:Rect id="backgroundImg"
left="1" right="1"
top="{topGroup ? topGroup.height : 0}"
bottom="{bottomGroup ? bottomGroup.height : 0}">
<s:fill>
<!-- BackgroundImage -->
<s:BitmapFill id="img" source="{backgroundImage}"
smooth="true" fillMode="scale" />
</s:fill>
</s:Rect>
Next you need to create a new class (my.package.CustomTitleWindow), that extends TitleWindow, set its skin, and bind the backgroundImage style:
<?xml version="1.0" encoding="utf-8"?>
<s:TitleWindow xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
skinClass="my.package.MyTitleWindowSkin">
<fx:Metadata>
[Style(name="backgroundImage", type="*")]
</fx:Metadata>
<mx:VBox width="100%" height="100%">
<mx:Text text="{IMyConstants.LOREMIPSUM}" width="100%" height="100%" />
<s:Button label="Do something" />
</mx:VBox>
</s:TitleWindow>
at the end a small test (which worked fine at my side, and i hope it's closer to what you're looking for):
<s:VGroup width="100%" height="100%" paddingLeft="10" paddingTop="10" paddingRight="10">
<my:CustomTitleWindow title="Window without background image"
width="100%" height="50%" />
<my:CustomTitleWindow title="Window with background image"
width="100%" height="50%" backgroundImage="{IMyConstants.MYLOGO}" />
</s:VGroup>
Update
For setting the skin and the background image from a css file, you only need some minor modifications:
Create a CSS file with content:
/* CSS file */
#namespace s "library://ns.adobe.com/flex/spark";
#namespace mx "library://ns.adobe.com/flex/mx";
#namespace my "your.package.*";
my|CustomTitleWindow {
skin-class: ClassReference("your.package.MyTitleWindowSkin");
}
.twWithBgImage {
background-image: Embed("icons/logo.png");
}
The test would look like:
<s:VGroup width="100%" height="100%" paddingLeft="10" paddingTop="10" paddingRight="10">
<my:CustomTitleWindow title="Window without background image"
width="100%" height="50%" />
<my:CustomTitleWindow title="Window with background image"
width="100%" height="50%" styleName="twWithBgImage" />
</s:VGroup>
and you need to remove the skin declaration from the CustomTitleWindow class: skinClass="your.package.MyTitleWindowSkin".
Of course you don't need to apply the skin to the my|CustomTitleWindow class, you could use it just for a css class, this way you surely don't need to modify your existing component.
Update -- without custom component
Forget the CustomTitleWindow class.
skinnedtw.css
/* CSS file */
#namespace s "library://ns.adobe.com/flex/spark";
#namespace mx "library://ns.adobe.com/flex/mx";
.twWithBgImage {
skin-class: ClassReference("your.package.MyTitleWindowSkin");
background-image: Embed("icons/logo.png");
}
TestApp.mxml
<?xml version="1.0" encoding="utf-8"?>
<s:WindowedApplication xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx">
<fx:Style source="assets/skinnedtw.css" />
<s:VGroup width="100%" height="100%" paddingLeft="10" paddingTop="10" paddingRight="10">
<s:TitleWindow title="Window without background image"
width="100%" height="50%">
<mx:VBox width="100%" height="100%">
<mx:Text text="{IMyConstants.LOREMIPSUM}" width="100%" height="100%" />
<s:Button label="Do something" />
</mx:VBox>
</s:TitleWindow>
<s:TitleWindow title="Window with background image"
width="100%" height="50%" styleName="twWithBgImage">
<mx:VBox width="100%" height="100%">
<mx:Text text="{IMyConstants.LOREMIPSUM}" width="100%" height="100%" />
<s:Button label="Do something" />
</mx:VBox>
</s:TitleWindow>
</s:VGroup>
</s:WindowedApplication>
My output still looks like this:
if you don't have explicit members in your mx:TitleWindow, than you should consider using
a spark BorderContainer as its first child, since you can specify a background image to that.
i'm thinking of something like this:
<?xml version="1.0" encoding="utf-8"?>
<mx:TitleWindow xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx" layout="absolute"
width="400" height="300" backgroundAttachment="">
<s:BorderContainer backgroundImage="{IMyConstants.MYLOGO}"
width="100%" height="100%" backgroundAlpha=".5" />
<mx:VBox width="100%" height="100%">
<mx:Text text="{IMyConstants.LOREMIPSUM}" width="100%" height="100%" />
<mx:Button label="Do something" />
</mx:VBox>
</mx:TitleWindow>
i hope i understood your problem, and this helps.

Flex 4: Controls in spark Panel still show when outside of panel size

I discovered this while doing some programmatic panel resizing:
Components in a spark Panel will still be visible when their location is outside the physical Panel boundaries. This does not happen with the mx Panel.
Running Flex 4.1 on Windows 7
I tried putting mx and spark controls in the spark Panel, and they both appear outside of the boundaries. Note this doesn't happen with the mx Panel.
What am I missing to make the spark behave like the mx?
Thanks !
Sample Code:
<?xml version="1.0" encoding="utf-8"?>
<s:WindowedApplication xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx">
<fx:Declarations>
<!-- Place non-visual elements (e.g., services, value objects) here -->
</fx:Declarations>
<s:Panel x="6" y="8" width="157" height="200">
<s:Label x="2" y="10" text="ABCDEFGHIJKL" width="258" height="35" textAlign="right"/>
<mx:Label text="Label" x="232" y="55"/>
<mx:Button x="125" y="96" label="Button"/>
</s:Panel>
<mx:Panel x="10" y="216" width="200" height="200" layout="absolute">
<mx:Label x="0" y="46" text="Label" width="217" textAlign="right"/>
<mx:Button x="163" y="88" label="Button"/>
</mx:Panel>
</s:WindowedApplication>
You may put a s:Group in them and set clipAndEnableScrolling="true". It's quite similar to CSS's overflow:hidden.

Flex - How to change open DropDownList height

Using FB4, I want to change the height of an open spark DropDownList. By default, it shows up to 6 items before scrolling. My dropdownlist contains 7 items, so I want to change the height of the open dropdown list to fit all 7 items without scrolling. As a workaround, I've changed the font size of the items so that they are smaller and all 7 fit, but the smaller font doesn't look good. Is there a way to change this height? I'm rather new to Flash, so if it's a complicated solution, please be detailed :-).
Isn't it easier if you use the property requestedRowCount of the verticalLayout?
<s:DropDownList dataProvider="{myDataProvider}">
<s:layout>
<s:VerticalLayout requestedRowCount="10"/>
</s:layout>
</s:DropDownList>
The issue is, in Flex 4, the DropDownListSkin has defined maxHeight="134" for the default skin you are probably using. That forces the scrollbar to appear if the objects stretch beyond that height. All you need to do is copy/paste their DropDownListSkin code into a custom skin, and apply that to your DropDownList via CSS:
VariableHeightDropDownListSkin
<?xml version="1.0" encoding="utf-8"?>
<s:Skin xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
alpha.disabled=".5">
<!-- host component -->
<fx:Metadata>
<![CDATA[
/**
* #copy spark.skins.spark.ApplicationSkin#hostComponent
*/
[HostComponent("spark.components.DropDownList")]
]]>
</fx:Metadata>
<s:states>
<s:State name="normal" />
<s:State name="open" />
<s:State name="disabled" />
</s:states>
<s:PopUpAnchor id="popUp" displayPopUp.normal="false" displayPopUp.open="true" includeIn="open"
left="0" right="0" top="0" bottom="0" itemDestructionPolicy="auto"
popUpPosition="below" popUpWidthMatchesAnchorWidth="true">
<!-- removed maxHeight! -->
<s:Group id="dropDown" minHeight="22">
<!-- border/fill -->
<s:Rect left="0" right="0" top="0" bottom="0">
<s:stroke>
<s:SolidColorStroke color="0x5380D0" />
</s:stroke>
<s:fill>
<s:SolidColor color="0xFFFFFF" />
</s:fill>
</s:Rect>
<s:Scroller left="0" top="0" right="0" bottom="0" focusEnabled="false" minViewportInset="1">
<s:DataGroup id="dataGroup" itemRenderer="spark.skins.spark.DefaultItemRenderer">
<s:layout>
<s:VerticalLayout gap="0" horizontalAlign="contentJustify"/>
</s:layout>
</s:DataGroup>
</s:Scroller>
<s:filters>
<s:DropShadowFilter blurX="20" blurY="20" distance="7" angle="90" alpha="0.45" color="0x6087CC" />
</s:filters>
</s:Group>
</s:PopUpAnchor>
<s:Button id="openButton" left="0" right="0" top="0" bottom="0" focusEnabled="false"
skinClass="spark.skins.spark.DropDownListButtonSkin" />
<s:Label id="labelDisplay" verticalAlign="middle" lineBreak="explicit"
mouseEnabled="false" mouseChildren="false"
left="7" right="30" top="2" bottom="2" width="75" verticalCenter="1" />
</s:Skin>
Sample Application
<?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/mx">
<fx:Style>
#namespace mx "library://ns.adobe.com/flex/mx";
#namespace s "library://ns.adobe.com/flex/spark";
s|DropDownList
{
skinClass: ClassReference("VariableHeightDropDownListSkin");
}
</fx:Style>
<s:DropDownList labelField="name" horizontalCenter="0" verticalCenter="0">
<s:layout>
<s:VerticalLayout requestedRowCount="7"/>
</s:layout>
<s:dataProvider>
<mx:ArrayCollection>
<fx:Object name="one"/>
<fx:Object name="two"/>
<fx:Object name="three"/>
<fx:Object name="four"/>
<fx:Object name="five"/>
<fx:Object name="six"/>
<fx:Object name="seven"/>
</mx:ArrayCollection>
</s:dataProvider>
</s:DropDownList>
</s:Application>
Let me know if that helps,
Lance
viatropos answer will work, however you should try and avoid overriding an entire skin as much as possible.
In this case, you will notice that in viatropos's VariableHeightDropDownListSkin code that the Group where he removed the maxHeight attribute, there is also an "id" specified.
Now look at the documentation for DropDownList and you will notice in the SkinParts section that there is a "dropDown" skin part. This is actually a property of DropDownList.
So instead of overriding the skin, you can simply use actionscript (I use UIComponent.DEFAULT_MAX_HEIGHT here, but you can use whichever you wish):
(MyDropDownList.dropDown as UIComponent).maxHeight = UIComponent.DEFAULT_MAX_HEIGHT;
Unfortunately, this is a lot more complicated in Flex 4 than it was in Flex 3:
You should be able to define a layout for the DropDownList with a higher requestedRowCount (details here), but for > 6 rows you need to do more work (Flex issue SDK-25364).
in FB3 it's rowCount cause the dropdown is a descendant of a list control. FB4 is probably similar.
myDropdown.rowCount = 7;
I usually use something more like
myDropdown.rowCount = myDataProvider.lenght();

Resources