in my project I have a Panel which is using a custom skin that I created based on the Spark Panel Skin. In this skin I added a Spark Scroller to the display Group (the "contentGroup"), to this group I add "ListItems" that have some Labels and Images.
Everything was working fine untill today when I noticed that when the vertical scroller reaches the bottom, there's still content to be shown as can be seen in the image:
(Since I can't post images, here's the link: http://s10.postimage.org/uwfqfqp15/Panel.jpg)
As you can see in the image the Scroller vertical scrollbar has reached the end but there is still something to below the bottom limit (as you can see my simple custom scrollbar hasn't reached the bottom).
Here's part of the panel skin code (the scroller part):
PanelSkin.mxml:
<s:Group id="algoGroup" x="0" y="0" width="100%" height="100%" minWidth="0" minHeight="0">
<s:Scroller id="contentScroller" x="0" y="0" width="85%" height="100%" minWidth="0" minHeight="0">
<s:Group id="contentGroup" x="0" y="0" width="85%" height="100%" minWidth="0" minHeight="0">
</s:Group>
</s:Scroller>
<componentes:customScroller id="contentScrollbar" x="10" y="10" width="10%" height="100%"/>
</s:Group>
ListaItem.mxml:
<?xml version="1.0" encoding="utf-8"?>
<s:Group xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
contentBackgroundAlpha="0.0"
currentState="Horizontal"
width.Horizontal="200" height.Horizontal="100"
height.Vertical="260" width.Vertical="128">
<s:states>
<s:State name="Horizontal"/>
<s:State name="Vertical"/>
</s:states>
<fx:Declarations>
<fx:Script>
<![CDATA[
import objectos.GlobalVars;
/*Vars - State -> Vertical
Bindable Vars -- Omitted
*/
public var ID:Number = -1;
public function resize(nW:Number, nH:Number):void
{
if(this.currentState == "Vertical")
{
_realIW = _iW2 = (_iW2 * nW) / _w2;
_realIH = _iH2 = (_iH2 * nH) / _h2;
if(_iW2 > _iH2)
_iW2 = _iH2;
else
_iH2 = _iW2;
_xImg = (_xImg * nW) / _w2;
_yImg = (_yImg * nH) / _h2;
_xTit = (_xTit * nW) / _w2;
_yTit = (_yTit * nH) / _h2;
Titulo.width = (Titulo.width * nW) / _w2;
Titulo.setStyle("fontSize", (GlobalVars.instance.getGlobal("fontSize") * 0.9));
_xDes = (_xDes * nW) / _w2;
if(Titulo.measureText(Titulo.text).width > Titulo.width)
_yDes = (_yDes * nH) / _h2;
else
_yDes = Titulo.y + Titulo.measureText(Titulo.text).height;
Descricao.width = (Descricao.width * nW) / _w2;
Descricao.setStyle("fontSize", (GlobalVars.instance.getGlobal("fontSize") * 0.7));
_xPre = (_xPre * nW) / _w2;
_yPre = (_yPre * nH) / _h2;
Preco.width = (Preco.width * nW) / _w2;
_xIco = (_xIco * nW) / _w2;
_yIco = (_yIco * nH) / _h2;
IconEspecial.width = (IconEspecial.width * nW) / _w2;
IconEspecial.height = (IconEspecial.height * nH) / _h2;
_xDeL = (_xDeL * nW) / _w2;
_yDeL = (_yDeL * nH) / _h2;
DescricaoL.width = (DescricaoL.width * nW) / _w2;
DescricaoL.setStyle("fontSize", (GlobalVars.instance.getGlobal("fontSize") * 0.7));
}
else
{
_realIW = _iW = (_iW * nW) / _w;
_realIH = _iH = (_iH * nH) / _h;
if(_iW > _iH)
_iW = _iH;
else
_iH = _iW;
Imagem.x = (Imagem.x * nW) / _w;
Imagem.y = (Imagem.y * nH) / _h;
Titulo.x = (Titulo.x * nW) / _w;
Titulo.y = (Titulo.y * nH) / _h;
Titulo.width = (Titulo.width * nW) / _w;
Titulo.setStyle("fontSize", (GlobalVars.instance.getGlobal("fontSize") * 0.9));
Descricao.x = (Descricao.x * nW) / _w;
Descricao.y = (Descricao.y * nH) / _h;
Descricao.width = (Descricao.width * nW) / _w;
Descricao.setStyle("fontSize", (GlobalVars.instance.getGlobal("fontSize") * 0.7));
Preco.x = (Preco.x * nW) / _w;
Preco.y = (Preco.y * nH) / _h;
Preco.width = (Preco.width * nW) / _w;
IconEspecial.x = (IconEspecial.x * nW) / _w;
IconEspecial.y = (IconEspecial.y * nH) / _h;
IconEspecial.width = (IconEspecial.width * nW) / _w;
IconEspecial.height = (IconEspecial.height * nH) / _h;
_sW = (_sW * nW) / _w;
_sY = (_sY * nH) / _h;
}
}
private function resizeImg():void
{
var ratio:Number = Imagem.contentWidth / Imagem.contentHeight;
if(Imagem.contentWidth > Imagem.contentHeight)
{
if(this.currentState == "Vertical")
{
Imagem.width = _iW2;
Imagem.height = _iW2 / ratio;
}
else
{
Imagem.width = _iW;
Imagem.height = _iW / ratio;
}
}
else
{
if(Imagem.contentHeight > Imagem.contentWidth)
{
if(this.currentState == "Vertical")
{
Imagem.height = _iH2;
Imagem.width = _iH2 * ratio;
}
else
{
Imagem.height = _iH;
Imagem.width = _iH * ratio;
}
}
else
{
if(this.currentState == "Vertical")
{
Imagem.height = (_iH2 > _iW2)?_iW2:_iH2;
Imagem.width = ((_iH2 > _iW2)?_iW2:_iH2) * ratio;
}
else
{
Imagem.height = (_iH > _iW)?_iW:_iH;
Imagem.width = ((_iH > _iW)?_iW:_iH) * ratio;
}
}
}
Imagem.x += (_realIW - Imagem.width) / 2;
Imagem.y += (_realIH - Imagem.height) / 2;
}
public function get useBar():Boolean
{
if(Separador != null)
return Separador.visible;
else
return false;
}
public function set useBar(value:Boolean):void
{
if(Separador != null)
Separador.visible = value;
}
]]>
</fx:Script>
<mx:Image id="Imagem" x.Horizontal="10" y.Horizontal="10" x.Vertical="{_xImg}" y.Vertical="{_yImg}" maintainAspectRatio="false" complete.Horizontal="resizeImg()" complete.Vertical="resizeImg()"/>
<s:Label id="Titulo" x="98" y="10" text="Label" width="102" maxDisplayedLines="2" x.Vertical="{_xTit}" y.Vertical="{_yTit}" verticalAlign.Vertical="middle" textAlign.Vertical="left"/>
<s:Label id="Descricao" x="98" y="43" text="Label" width="102" maxDisplayedLines="3" color="#999999" x.Vertical="{_xDes}" y.Vertical="{_yDes}"/>
<s:Label id="Preco" x="113" y="78" text="Label" width="87" maxDisplayedLines="1" x.Vertical="{_xPre}" y.Vertical="{_yPre}"/>
<mx:Image x="93" y="73" width="20" height="20" id="IconEspecial" x.Vertical="{_xIco}" y.Vertical="{_yIco}"/>
<mx:HRule id="Separador" x="0" y="{_sY}" width="{_sW}" strokeColor="#000000" shadowColor="#000000" includeIn="Horizontal"/>
<s:Label id="DescricaoL" x.Horizontal="1" y.Horizontal="177" x.Vertical="{_xDeL}" y.Vertical="{_yDeL}" text="Label" width="127" color="#999999" visible.Horizontal="false" maxDisplayedLines="3"/>
</s:Group>
Here's the code used to add the components dynamically (edited to include relevante parts only):
var item:ListaItem = new ListaItem();
var iW:Number = 0;
var iH:Number = 0;
if(yPos == -1 || xPos == -1)
{
yPos = 0 - ((_group.height - (10 * (_maxProdutosVisiveis - 1))) / _maxProdutosVisiveis) - 10;
xPos = 0;
}
yPos += ((_group.height - (10 * (_maxProdutosVisiveis - 1))) / _maxProdutosVisiveis) + 10;
xPos = 0;
iW = _group.width;
iH = ((_group.height - (10 * (_maxProdutosVisiveis - 1))) / _maxProdutosVisiveis);
item.x = xPos;
item.y = yPos;
item.ID = obj.idProduto;
item.Titulo.text = (obj.Titulo_Produto != null)?obj.Titulo_Produto:obj.Titulo;
item.Descricao.text = obj.Descricao;
item.Preco.text = obj.Valor + " €";
item.IconEspecial.source = this.specialIcon;
_margem = iH + 10;
item.addEventListener(MouseEvent.CLICK, goToApresentacao);
_group.addElement(item);
_components.addItem(item);
item.width = iW;
item.height = iH;
item.Imagem.source = obj.url;
_maxProdutosVisiveis
is the maximum visible products at the same time
obj
is the object holding the data for the ListItem
I think that I have included everything relevant, but feel free to ask for anything else.
Is there any way to solve this problem?
Thanks for your help :)
After hours of search and trying different approaches to the problem I noticed that I forgot to add the default height and width for the ListaItem.
Changing:
ListaItem.mxml:
<?xml version="1.0" encoding="utf-8"?>
<s:Group xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
contentBackgroundAlpha="0.0"
currentState="Horizontal"
width.Horizontal="200" height.Horizontal="100"
height.Vertical="260" width.Vertical="128">
To:
<?xml version="1.0" encoding="utf-8"?>
<s:Group xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
contentBackgroundAlpha="0.0"
currentState="Horizontal"
width="200" height="100"
height.Vertical="260" width.Vertical="128">
Makes everything work again. Thank you everyone anyway :)