2011-01-07 4 views
7

Я заполняю dropDownList с помощью arrayCollection строк. Я хочу, чтобы ширина элемента управления выпадающего списка соответствовала размеру (в пикселях) самой длинной строки в коллекции массивов. Проблема, с которой я столкнулся, - это: ширина шрифта строк в коллекции различна, например. «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); 
    } 

Любая идея или решение высоко ценится.

Благодаря

ответ

7

Чтобы получить более точные измерения, вы можете заполнить текстовое поле со строкой, а затем измерить ширину текста этого 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); 
+0

@Rose Поверьте, вам нужно добавить validateNow() вызов после присвоения строки, но перед проверкой textWidth/textHeight назначение строки приводит к недействительности размера, но пересчету от размера не является синхронным, поэтому вы должны принудительно выполнить валидацию – shaunhusain

+0

Отлично! Мне понравилось решение; У меня есть небольшая проблема. Он не получает правильную ширину пикселя. Я дал ему эту строку в массиве. var strings: Array = ["a", "giraffe", "foo", "объект ArrayCollection не представляет никакого"]; Теперь он получил ширину текста 245, но на самом деле размер был 276. Таким образом, полоса прокрутки отображается в моем выпадающем списке.Из вашего кода я удалил часть, которая имеет textFormat, поэтому я сделал функцию measureStr функцией 1 аргумента – Rose

+0

@Rose: TextFormat влияет на шрифт (-face и -family), который используется при измерении текста - он должен быть изменен в точности совпадать с раскрывающимся списком (хотя я не уверен, что это такое). После удаления материала textFormat он дает правильную длину? Если это так, я подозреваю, что это потому, что текстовый формат по умолчанию совпадает с тем, что используется в раскрывающемся списке. – Cameron

1

Я не редактировать собств на других людей Поста поэтому я отправляю это как отдельный ответ, но кредит должен пойти на Камерона, если это работает:

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, чтобы получить его на сцене, но с помощью AutoSize, кажется, работает нормально:

<?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

, но делает textField класс имеет validateNow() метод ?? http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/text/TextField.html?filter_flex=4.1&filter_flashplayer=10.1&filter_air=2 – Rose

+0

Дой! извините, опередил себя там, поэтому использовал для использования validateNow в этих сценариях ... вы, скорее всего, правы, поскольку TextField - это компонент Flash, а не Flex, схема проверки, о которой я говорил, применяется в компонентах Flex ... У меня есть сделайте это с помощью текстового поля, хотя также верьте, что вам может понадобиться установить размер авто или что-то в этом роде ... опубликует правило выше в течение нескольких минут – shaunhusain

+0

Интересно ... Вы уверены, что это 'autoSize' делает это а не то, что текстовое поле добавляется на сцену? – Cameron

0

Это более полированная версия некоторых из вышеперечисленного кода. Учет строк (html break и \ 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-инструментах: https://github.com/charlesclements/as3-tools

Кроме того, наш Flash/JS брат Джек Дойл @ GreenSock имеет некоторые полезные вещи, которые нужно делать с манипулированием текстом. Ну стоит ли это проверить: http://www.greensock.com/splittext/

Смежные вопросы