2011-01-07 43 views
7

Tôi đang điền một dropDownList với mảngCollection của chuỗi. Tôi muốn chiều rộng của điều khiển danh sách thả xuống để phù hợp với kích thước (tính bằng pixel) của chuỗi dài nhất trong bộ sưu tập mảng. Vấn đề tôi đang gặp phải là: chiều rộng phông chữ của các chuỗi trong bộ sưu tập khác nhau, ví dụ: 'W' trông rộng hơn 'l'. Vì vậy, tôi ước tính chiều rộng của một nhân vật là 8 pixel nhưng đó không phải là khá gọn gàng. Nếu một chuỗi có nhiều 'W' và 'M' gặp phải, ước tính sai. Vì vậy, tôi muốn chiều rộng pixel chính xác của chuỗi. Làm thế nào tôi có thể nhận được độ dài chính xác của một chuỗi bằng pixel ??Độ dài của một chuỗi theo pixel

Giải pháp của tôi rằng ước tính tất cả các nhân vật là 8 pixels rộng được đưa ra dưới đây:

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); 
    } 

Bất kỳ ý tưởng hoặc giải pháp được đánh giá cao.

Cảm ơn

Trả lời

7

Để có được một phép đo chính xác hơn, bạn có thể cư một TextField với chuỗi, sau đó đo chiều rộng của văn bản của TextField đó.

Code:

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); 
} 

Cách sử dụng:

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 kích thước không đồng bộ, do đó bạn phải ép buộc xác thực – shaunhusain

+0

Tuyệt vời! Tôi thích giải pháp; Tôi đã có một vấn đề nhỏ. Nó không nhận được chiều rộng pixel đúng. Tôi đã cho nó chuỗi này trong mảng. var strings: Array = ["a", "hươu cao cổ", "foo", "Đối tượng ArrayCollection không đại diện cho bất kỳ"]; Bây giờ nó có độ rộng văn bản là 245 nhưng trên thực tế kích thước là 276. Vì vậy, một thanh cuộn hiển thị trên danh sách thả xuống của tôi.Từ mã của bạn, tôi đã xóa phần có textFormat, vì vậy tôi đã thực hiện chức năng measureStr một hàm đối số – Rose

+0

@Rose: TextFormat ảnh hưởng đến phông chữ (-face và -family) được sử dụng khi đo văn bản - nó phải được thay đổi khớp với danh sách thả xuống chính xác (mặc dù tôi không chắc đó là gì). Sau khi loại bỏ các công cụ textFormat, nó có cho độ dài phù hợp không? Nếu vậy, tôi nghi ngờ đó là vì định dạng văn bản mặc định giống với những gì đang được sử dụng trong danh sách thả xuống. – Cameron

1

Tôi không có chỉnh sửa priv về bài đăng của người khác vì vậy tôi gửi bài này như một câu trả lời riêng biệt nhưng tín dụng nên đến Cameron nếu công trình này:

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); 
} 

Nếu tôi thấy điều đó xảy ra và được chỉnh sửa, tôi sẽ xóa chế độ này để vệ sinh.

Xin lỗi cho bài đăng rác ban đầu đã cố gắng trả lời câu hỏi vừa làm như vậy một cách sai lầm ... dù sao đi nữa thử nghiệm cái này và nó dường như hoạt động. Tôi đã làm điều này trong Flex nhưng bạn sẽ có thể chỉ cần sử dụng một phần AS3 không có vấn đề tôi chỉ quấn lên TextField trong một UIComponent để có được nó trên sân khấu nhưng sử dụng AutoSize dường như làm việc tốt:

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

nhưng hiện textField lớp đã validateNow() phương pháp ?? 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

Doy! xin lỗi đã đi trước bản thân mình ở đó để sử dụng validateNow trong những tình huống này ... bạn rất có thể đúng như TextField là một thành phần Flash không phải là Flex, lược đồ xác thực mà tôi đã nói về áp dụng trong các thành phần Flex ... Tôi có thực hiện điều này với một trường văn bản mặc dù cũng tin rằng bạn có thể cần phải thiết lập kích thước tự động hoặc một cái gì đó dọc theo những dòng ... sẽ đăng một chỉnh sửa ở trên trong một vài phút – shaunhusain

+0

Thú vị ... Bạn có chắc chắn là 'autoSize' đang làm nó và không thực tế là hộp văn bản đang được thêm vào giai đoạn? – Cameron

0

Đây là một phiên bản được đánh bóng hơn của một số mã ở trên. Kế toán cho các ngắt dòng (ngắt html và \ n) và vô hiệu hóa đối tượng Textfield đã tạo với một số tối ưu hóa khác. Hy vọng điều này là hữu ích.

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); 

Nếu bạn thích này trong một lớp học, kiểm tra xem nó ra trong khuôn khổ GIT tôi: https://github.com/charlesclements/as3-tools/blob/master/net/charlesclements/util/text/TextUtil.as

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

Ngoài ra, Flash của chúng tôi/JS anh trai Jack Doyle @ GreenSock có một số công cụ hữu ích để làm với thao tác văn bản. Bạn nên kiểm tra xem nó ra: http://www.greensock.com/splittext/

Các vấn đề liên quan