Flex:用于组合框的自定义项目渲染器控件将截断文本
我已经实现了一个自定义项目渲染器,该项目渲染器正在与我正在处理的Flex项目上的组合框一起使用。它显示和图标以及每个项目的一些文本。唯一的问题是,当文本较长时,菜单的宽度不能正确调整,并且显示时文本将被截断。我尝试调整所有明显的属性以缓解此问题,但没有成功。有谁知道如何使组合框菜单的宽度适当地缩放到它呈现的任何数据?
我的自定义项目渲染器实现是:
<?xml version="1.0" encoding="utf-8"?> <mx:HBox xmlns:mx="http://www.adobe.com/2006/mxml" styleName="plain" horizontalScrollPolicy="off"> <mx:Image source="{data.icon}" /> <mx:Label text="{data.label}" fontSize="11" fontWeight="bold" truncateToFit="false"/> </mx:HBox>
我的组合框使用它的方式如下:
<mx:ComboBox id="quicklinksMenu" change="quicklinkHandler(quicklinksMenu.selectedItem.data);" click="event.stopImmediatePropagation();" itemRenderer="renderers.QuickLinkItemRenderer" width="100%"/>
编辑:
我应该澄清一下:我可以将组合框上的dropdownWidth属性设置为任意大的值,这将使所有内容都适合,但它将太宽。由于此组合框中显示的数据是通用的,因此我希望它自动将其大小调整为dataprovider中的最大元素(flex文档说它将做到这一点,但我感觉我的自定义项目渲染器会以某种方式破坏该行为)
解决方案
只是一个随机的想法(不知道是否有帮助):
尝试将父级HBox和Label的宽度设置为100%。这就是通常固定成类似于我碰到的任何问题。
我们是否尝试过使用calculatePreferredSizeFromData()方法?
protected override function calculatePreferredSizeFromData(count:int):Object
这个答案可能为时已晚,但是我对DataGrid的列宽有一个非常相似的问题。
经过大量的整理之后,我决定在私有TextField中预渲染文本,从中获取渲染文本的宽度,并在所有适当的调整大小类型事件上显式设置列的宽度。有点骇人听闻,但如果我们没有太多更改数据,就可以很好地工作。
我们将需要做两件事:
- 对于文本,请使用mx.controls.Text(支持文本换行),而不要使用mx.controls.Label
- 设置comboBox的
dropdownFactory.variableRowHeight = true
-这个dropdownFactory通常是List的子类,我们在ComboBox上设置的itemRenderer将用于呈现列表中的每个项目
而且,不要明确地设置comboBox.dropdownWidth
- 让comboBox.width的
的默认值被用作下拉列表的宽度。
如果看一下mx.controls.ComboBase的measure方法,我们会发现comboBox计算出的measuredMinWidth是文本宽度和comboBox按钮宽度的总和。
// Text fields have 4 pixels of white space added to each side // by the player, so fudge this amount. // If we don't have any data, measure a single space char for defaults if (collection && collection.length > 0) { var prefSize:Object = calculatePreferredSizeFromData(collection.length); var bm:EdgeMetrics = borderMetrics; var textWidth:Number = prefSize.width + bm.left + bm.right + 8; var textHeight:Number = prefSize.height + bm.top + bm.bottom + UITextField.TEXT_HEIGHT_PADDING; measuredMinWidth = measuredWidth = textWidth + buttonWidth; measuredMinHeight = measuredHeight = Math.max(textHeight, buttonHeight); }
@defmeta提到的calculatePreferredSizeFromData方法(在mx.controls.ComboBox中实现)假定数据渲染器只是一个文本字段,并使用flash.text.lineMetrics从标签字段中的标签字段计算文本宽度数据对象。如果要向项目渲染器添加其他可视元素,并在计算其自身大小时让" ComboBox"考虑其大小,则必须扩展" mx.controls.ComboBox"类并覆盖" calculatePreferredSizeFromData"像这样的方法:
override protected function calculatePreferredSizeFromData(count:int):Object { var prefSize:Object = super.calculatePrefferedSizeFromData(count); var maxW:Number = 0; var maxH:Number = 0; var bookmark:CursorBookmark = iterator ? iterator.bookmark : null; var more:Boolean = iterator != null; for ( var i:int = 0 ; i < count ; i++) { var data:Object; if (more) data = iterator ? iterator.current : null; else data = null; if(data) { var imgH:Number; var imgW:Number; //calculate the image height and width using the data object here maxH = Math.max(maxH, prefSize.height + imgH); maxW = Math.max(maxW, prefSize.width + imgW); } if(iterator) iterator.moveNext(); } if(iterator) iterator.seek(bookmark, 0); return {width: maxW, height: maxH}; }
如果可能的话,将图像尺寸存储在数据对象中,并将这些值用作" imgH"和" imgW",这将使尺寸调整变得更加容易。
编辑:
如果我们要在图像之外向渲染器添加元素(如标签),则在遍历数据元素时还必须计算其大小,并在计算" maxH"和" maxW"时将这些尺寸考虑在内。