字符串的长度,以像素为单位

问题描述 投票:8回答:4

我正在用字符串的arrayCollection填充dropDownList。我希望下拉列表控件的宽度与数组集合中最长字符串的大小(以像素为单位)匹配。我面临的问题是:集合中字符串的字体宽度不同,例如“ W”看起来比“ l”宽。因此,我估计一个字符的宽度为8像素,但这并不是很整齐。如果遇到具有许多“ W”和“ M”的字符串,则估计是错误的。所以我想要精确的字符串像素宽度。如何获得以像素为单位的字符串的确切长度?

我的估计所有字符为8像素宽的解决方案如下:

public function populateDropDownList():void{
    var array:Array = new Array("o","two","three four five six seven eight wwww");
    var sampleArrayCollection:ArrayCollection = new ArrayCollection(array);
    var customDropDownList:DropDownList = new DropDownList();
    customDropDownList.dataProvider=sampleArrayCollection;
    customDropDownList.prompt="Select ...";
    customDropDownList.labelField="Answer Options:";
    //calculating the max width
    var componentWidth=10; //default
    for each(var answerText in array){
     Alert.show("Txt size: "+ answerText.length + " pixels: " + answerText.length*9); 
     if(answerText.length * 8 > componentWidth){
      componentWidth=answerText.length * 8;
     }
    }
    customDropDownList.width=componentWidth;
    answers.addChild(customDropDownList);
   }

任何想法或解决方案都受到高度重视。

谢谢

actionscript-3 string fonts drop-down-menu flex4
4个回答
7
投票

为了获得更准确的测量结果,可以用字符串填充TextField,然后测量该TextField文本的宽度。

代码:

function measureString(str:String, format:TextFormat):Rectangle {
    var textField:TextField = new TextField();
    textField.defaultTextFormat = format;
    textField.text = str;

    return new Rectangle(0, 0, textField.textWidth, textField.textHeight);
}

用法:

var format:TextFormat = new TextFormat();
format.font = "Times New Roman";
format.size = 16;

var strings:Array = [ "a", "giraffe", "foo", "!" ];

var calculatedWidth:Number = 50;    // Set this to minimum width to start with

for each (var str:String in strings) {
    var stringWidth:Number = measureString(str, format).width;
    if (stringWidth > calculatedWidth) {
        calculatedWidth = stringWidth;
    }
}

trace(calculatedWidth);

1
投票

我没有在其他人的帖子上编辑priv,所以我将其发布为单独的答案,但如果可行,功劳应归功于Cameron:

function measureString(str:String, format:TextFormat):Rectangle {
    var textField:TextField = new TextField();
    textField.autoSize = TextFieldAutoSize.LEFT;
    textField.defaultTextFormat = format;
    textField.text = str;

    return new Rectangle(0, 0, textField.textWidth, textField.textHeight);
}

如果我看到了,并且对其进行了编辑,则出于清洁目的,将其删除。

很抱歉,垃圾站最初试图回答这个问题,只是这样做是错误的。。。无论如何测试了这个问题,它似乎起作用了。我在Flex中进行了此操作,但是您应该可以只使用AS3部分,没问题,我只是将文本字段包装在UIComponent中以使其在舞台上使用,但是使用自动调整大小似乎可以正常工作:

<?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" minWidth="955" minHeight="600">
    <fx:Declarations>
        <!-- Place non-visual elements (e.g., services, value objects) here -->
    </fx:Declarations>
    <fx:Script>
        <![CDATA[
            import mx.core.UIComponent;
            protected function textinput1_changeHandler(event:TextOperationEvent):void
            {
                // TODO Auto-generated method stub

                var rect:Rectangle = measureString(event.target.text);
                holderBox.graphics.clear();
                holderBox.graphics.beginFill(0xFF0000);
                holderBox.graphics.drawRect(rect.x,rect.y,rect.width,rect.height);
            }

            private function measureString(str:String):Rectangle {
                var textField:TextField = new TextField();
                textField.autoSize = TextFieldAutoSize.LEFT;
                textField.text = str;
                var uiComponent:UIComponent = new UIComponent();
                uiComponent.addChild(textField);
                holderBox.addChild(uiComponent);

                return new Rectangle(0, 0, textField.textWidth, textField.textHeight);
            }

        ]]>
    </fx:Script>
    <mx:VBox>
        <s:TextInput text="" change="textinput1_changeHandler(event)"/>
        <mx:Box id="holderBox"/>
    </mx:VBox>
</s:Application>

0
投票

这是上面某些代码的更完善的版本。考虑换行符(html换行和\ n),并通过其他一些优化使创建的Textfield对象无效。希望这会有所帮助。

function measureString(str:String, font:String="Times New Roman", size:Number=12):Rectangle 
{
    var textField:TextField = new TextField();
    textField.defaultTextFormat = new TextFormat( font, size );
    textField.border = true;
    textField.multiline = true;
    textField.autoSize = TextFieldAutoSize.LEFT;
    textField.htmlText = str;
    // Grab with and height before nullifying Textfield.
    var w:Number = textField.textWidth;
    var h:Number = textField.textHeight;
    //addChild( textField );// This will add the Textfield to the stage so you can visibly see it.
    //if( contains( textField ) ) removeChild( textField );// If it exists onstage, remove it.
    textField = null;//nullify it to make it available for garbage collection.
    return new Rectangle(0, 0, w, h);
}

var str:String = "Jeremy is a good boy.<br>He also has a red bike. \nSometimes Jeremy rides his bike to the store to buy bread for his family.<br>He likes wholewheat.";
trace( measureString( str, "Times New Roman", 25 ).width );

[如果您在课堂上喜欢这个,请在​​我的GIT框架中查看:https://github.com/charlesclements/as3-tools/blob/master/net/charlesclements/util/text/TextUtil.as

AS3-tools:https://github.com/charlesclements/as3-tools

[此外,我们的Flash / JS兄弟Jack Doyle @ GreenSock与处理文本有关一些方便的事情。值得一试:http://www.greensock.com/splittext/


0
投票

这里是我为Java编写的例程。我想您可以将其转换为Javascript或其他格式。

并不精确,但是给出了大概的答案。假定空间大约为200宽,而M和W大约为1000宽。显然,您需要根据您的特定字体大小进行缩放。

static int picaSize(String s)
{
    // the following characters are sorted by width in Arial font
    String lookup = " .:,;'^`!|jl/\\i-()JfIt[]?{}sr*a\"ce_gFzLxkP+0123456789<=>~qvy$SbduEphonTBCXY#VRKZN%GUAHD@OQ&wmMW";
    int result = 0;
    for (int i = 0; i < s.length(); ++i)
    {
        int c = lookup.indexOf(s.charAt(i));
        result += (c < 0 ? 60 : c) * 7 + 200;
    }
    return result;
}
© www.soinside.com 2019 - 2024. All rights reserved.