Flex:组合框控件的自定义项目渲染器截断文本

Posted

技术标签:

【中文标题】Flex:组合框控件的自定义项目渲染器截断文本【英文标题】:Flex: Custom Item Renderer For Combobox controls truncates text 【发布时间】:2010-09-11 08:42:07 【问题描述】:

我已经实现了一个自定义项渲染器,我在我正在处理的 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" />

编辑: 我应该澄清一下:我可以将组合框上的 dropdownWidth 属性设置为任意大的值 - 这将使一切都合适,但它会太宽。由于此组合框中显示的数据是通用的,因此我希望它自动将自身调整为 dataprovider 中最大的元素(flex 文档说它会这样做,但我觉得我的自定义项目渲染器以某种方式破坏了这种行为)

【问题讨论】:

【参考方案1】:

只是一个随机的想法(不知道这是否有帮助):

尝试将父 HBox 和 Label 的宽度设置为 100%。这通常可以解决我遇到的任何类似问题。

【讨论】:

我试过了,但是很可惜 - 它没有效果。似乎影响菜单宽度的唯一因素是为组合框上的“提示”属性指定的值的长度。【参考方案2】:

您是否尝试过使用 calculatePreferredSizeFromData() 方法?

protected override function calculatePreferredSizeFromData(count:int):Object

【讨论】:

【参考方案3】:

这个答案可能为时已晚,但我在 DataGrid 的列宽方面遇到了非常相似的问题。

经过多次思考,我决定在私有 TextField 中预渲染我的文本,从中获取渲染文本的宽度,并在所有适当的调整大小类型事件上显式设置列的宽度。有点 hack-y,但如果你没有大量变化的数据,它就足够了。

【讨论】:

【参考方案4】:

你需要做两件事:

对于文本,使用mx.controls.Text(支持文本换行)而不是mx.controls.Label 设置comboBox的dropdownFactory.variableRowHeight=true——这个dropdownFactory通常是List的子类,你在ComboBox上设置的itemRenderer是用来渲染列表中每一项的

并且,不要显式设置comboBox.dropdownWidth -- 让comboBox.width 的默认值用作下拉菜单宽度。

【讨论】:

【参考方案5】:

如果您查看mx.controls.ComboBasemeasure 方法,您会看到组合框将measuredMinWidth 计算为文本宽度和组合框按钮宽度之和。

    // 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.lineMetricsdata 对象中的标签字段计算文本宽度。如果您想向项目渲染器添加额外的视觉元素并让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;
 

如果可能,将图像尺寸存储在数据对象中并将这些值用作imgHimgW,这将使调整大小更加容易。

编辑:

如果您要向渲染添加除图像之外的元素,例如标签,您还必须在遍历数据元素时计算它们的大小,并在计算 maxH 和 @987654336 时考虑这些尺寸@。

【讨论】:

以上是关于Flex:组合框控件的自定义项目渲染器截断文本的主要内容,如果未能解决你的问题,请参考以下文章

使用 flex css 样式时的自定义控件宽度

Flex TextInput 控件:搜索样式渲染

Xamarin.Forms 中 Picker 的自定义渲染器

Flex:使用项目渲染器

Flex:在列表项渲染器中缓存图像?

Flex:如何在加载组件之前检索数据?