8 Stimmen

Länge eines Strings in Pixeln

Ich fülle ein Drop-Down-Listenfeld mit einer ArrayCollection von Zeichenfolgen. Ich möchte, dass die Breite des Dropdown-Listenfelds mit der Größe (in Pixeln) der längsten Zeichenfolge in der ArrayCollection übereinstimmt. Das Problem, dem ich gegenüberstehe, ist folgendes: Die Schriftbreite der Zeichen in der Sammlung ist unterschiedlich, z. B. sieht 'W' breiter aus als 'l'. Also schätze ich die Breite eines Zeichens auf 8 Pixel, aber das ist nicht sehr genau. Wenn eine Zeichenfolge mit vielen 'W' und 'M' vorkommt, ist die Schätzung falsch. Also möchte ich die genaue Pixelbreite von Zeichenfolgen haben. Wie kann ich die genaue Länge einer Zeichenfolge in Pixeln erhalten??

Meine Lösung, die alle Zeichen auf 8 Pixel breit schätzt, ist nachstehend angegeben:

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="Auswählen ...";
    customDropDownList.labelField="Antwortoptionen:";
    //Berechnung der maximalen Breite
    var componentWidth=10; //Standardwert
    for each(var answerText in array){
     Alert.show("Txt Größe: "+ answerText.length + " pixel: " + answerText.length*9); 
     if(answerText.length * 8 > componentWidth){
      componentWidth=answerText.length * 8;
     }
    }
    customDropDownList.width=componentWidth;
    answers.addChild(customDropDownList);
   }

Jeder Vorschlag oder Lösung ist sehr geschätzt.

Danke

7voto

Cameron Punkte 91138

Um eine genauere Messung zu erhalten, können Sie ein TextField mit dem String füllen und dann die Breite des TextFields messen.

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

Verwendung:

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

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

var calculatedWidth:Number = 50;    // Setze dies als minimale Breite zu Beginn

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

trace(calculatedWidth);

0 Stimmen

@Rose Glauben Sie, dass Sie nach dem Zuweisen des Strings, aber vor dem Überprüfen der textWidth/textHeight einen validateNow() Aufruf hinzufügen müssen. Das Zuweisen des Strings führt zu einer Ungültigmachung der Größe, aber die Neuberechnung der Größe erfolgt nicht synchron, daher müssen Sie die Validierung erzwingen.

0 Stimmen

Großartig! Mir hat die Lösung gefallen; ich habe jedoch ein kleines Problem. Es bekommt nicht die richtige Pixelbreite. Ich habe ihm diese Zeichenfolge im Array gegeben.
var strings:Array = [ "a", "giraffe", "foo", "Das ArrayCollection-Objekt repräsentiert nicht" ];
Jetzt war die Textbreite 245, aber tatsächlich war die Größe 276. Also zeigt eine Scrollleiste in meiner Dropdown-Liste. Aus Ihrem Code habe ich den Teil entfernt, der textFormat hat, also habe ich die measureStr-Funktion zu einer Funktion mit einem Argument gemacht.

0 Stimmen

@Rose: Der Textformat beeinflusst die Schriftart (-face und -family), die verwendet wird, wenn der Text gemessen wird - er sollte geändert werden, um genau dem der Dropdown-Liste zu entsprechen (obwohl ich nicht sicher bin, was das ist). Nachdem der Textformat entfernt wurde, gibt es die richtige Länge? Wenn ja, vermute ich, dass dies daran liegt, dass das Standardtextformat dasselbe ist wie das, was in der Dropdown-Liste verwendet wird.

1voto

shaunhusain Punkte 19562

Ich habe keine Bearbeitungsberechtigung für die Beiträge anderer Personen, daher poste ich dies als separate Antwort, aber das Guthaben sollte an Cameron gehen, wenn dies funktioniert:

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

Wenn ich sehe, dass es funktioniert und seins bearbeitet wird, würde ich dieses hier für die Sauberkeit löschen.

Entschuldigung für den Müllbeitrag am Anfang, ich habe versucht, die Frage zu beantworten, aber falsch gemacht... wie auch immer, habe dies getestet und es scheint zu funktionieren. Ich habe dies in Flex gemacht, aber du kannst wahrscheinlich einfach den AS3-Teil nutzen, kein Problem, ich habe den Textfeld einfach in ein UIComponent verpackt, um es auf die Bühne zu bringen, aber die Autosize-Funktion scheint gut zu funktionieren:

0 Stimmen

Aber hat die textField-Klasse eine validateNow() Methode?? help.adobe.com/de_DE/FlashPlatform/reference/actionscript/3/‌​…

0 Stimmen

Doh! Entschuldigung, ich war voreilig dort, weil ich so daran gewöhnt bin, validateNow in diesen Szenarien zu verwenden... Du hast wahrscheinlich recht, da TextField ein Flash-Komponente und kein Flex ist, das Validierungsschema, über das ich gesprochen habe, gilt in Flex-Komponenten... Ich habe dies jedoch auch mit einem Textfeld gemacht, glaube, du musst die automatische Größenanpassung oder etwas in dieser Art setzen... werde gleich eine Bearbeitung oben posten in ein paar Minuten

0 Stimmen

Interessant... Bist du sicher, dass es das autoSize ist und nicht die Tatsache, dass das Textfeld zur Bühne hinzugefügt wird?

0voto

charlesclements Punkte 86

Dies ist eine verbesserte Version einiger obiger Codes. Berücksichtigung von Zeilenumbrüchen (HTML-Umbruch und \n) und Neutralisierung des erstellten Textfeldobjekts mit einigen anderen Optimierungen. Hoffe das ist hilfreich.

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;
    // Holen Sie sich Breite und Höhe, bevor Sie Textfeld neutralisieren.
    var w:Number = textField.textWidth;
    var h:Number = textField.textHeight;
    //addChild( textField );// Dadurch wird das Textfeld auf der Bühne hinzugefügt, damit Sie es sichtbar sehen können.
    //if( contains( textField ) ) removeChild( textField );// Wenn es sich auf der Bühne befindet, entfernen Sie es.
    textField = null;// Neutralisieren Sie es, um es für die Müllsammlung verfügbar zu machen.
    return new Rectangle(0, 0, w, h);
}

var str:String = "Jeremy ist ein guter Junge.Er hat auch ein rotes Fahrrad. \nManchmal fährt Jeremy mit seinem Fahrrad zum Laden, um Brot für seine Familie zu kaufen.Er mag Vollkornbrot.";
trace( measureString( str, "Times New Roman", 25 ).width );

Wenn Sie dies lieber in einer Klasse möchten, schauen Sie es sich in meinem GIT-Framework an: https://github.com/charlesclements/as3-tools/blob/master/net/charlesclements/util/text/TextUtil.as

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

Außerdem hat unser Flash/JS-Bruder Jack Doyle @ GreenSock einige nützliche Sachen zur Manipulation von Texten. Es lohnt sich, es sich anzusehen: http://www.greensock.com/splittext/

0voto

John Henckel Punkte 8519

Hier ist ein von mir geschriebenes Programm für Java. Ich denke, du kannst es in Javascript oder was auch immer konvertieren.

Es ist nicht genau, aber gibt eine ungefähre Antwort. Es geht davon aus, dass ein Leerzeichen etwa 200 Breite hat und M und W etwa 1000 Breite haben. Offensichtlich musst du das basierend auf deiner speziellen Schriftgröße skalieren.

static int picaSize(String s)
{
    // die folgenden Zeichen sind nach Breite in der Arial-Schriftart sortiert
    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;
}

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X