2011-05-20 75 views

回答

2

好吧,这是最有可能不完全是你正在寻找的解决方案,因为我的解决方案是在标准的闪存核心TextField类,而不是一些特定的Flex compontent针对性。但我想通过查看代码,您应该能够了解发生的情况并将其转移到组件。

基本上我做的是我总是检查当前光标在哪里使用选择,然后我得到响应线并在背景中绘制某种突出显示当前行。请注意,我只是简单地基于单个字体,因此它的行高总是相同的。但是,您可以通过使用TextLineMetrics类并在更精确地计算实际偏移量的情况下,针对单个文本字段中的不同字体进行工作。由于这是更多的工作,并且突出显示可能仅适用于单一字体环境,所以我将其排除在外。我的例子使用Courier,但它应该能够自动处理任何大小的字体。

package 
{ 
    import flash.display.Shape; 
    import flash.display.Sprite; 
    import flash.events.Event; 
    import flash.text.TextField; 
    import flash.text.TextFieldType; 
    import flash.text.TextFormat; 
    import flash.text.TextLineMetrics; 

    public class HighlightedTextField extends Sprite 
    { 
     private var textField:TextField; 
     private var highlighter:Shape; 
     private var metrics:TextLineMetrics;   
     private var selectionBegin:int = -1; 
     private var selectionEnd:int = -1; 
     private var lineBegin:int = -1; 
     private var lineEnd: int = -1; 

     public function HighlightedTextField() 
     { 
      this.graphics.beginFill(0xEEEEEE); 
      this.graphics.drawRect(5, 5, 290, 290); 
      this.graphics.endFill(); 

      // construct text field    
      textField = new TextField(); 
      textField.width = 280; 
      textField.height = 280; 
      textField.x = 10; 
      textField.y = 10; 
      textField.background = false; 
      textField.selectable = true; 
      textField.multiline = true; 
      textField.defaultTextFormat = new TextFormat('Courier', 12); 
      textField.type = TextFieldType.INPUT; 

      // construct line highlighter 
      highlighter = new Shape(); 
      highlighter.graphics.beginFill(0xCCCCCC); 
      highlighter.graphics.drawRect(0, 0, textField.width, 1); 
      highlighter.x = textField.x; 
      highlighter.y = textField.y; 

      this.addChild(highlighter); 
      this.addChild(textField); 
      this.addEventListener(Event.ENTER_FRAME, setHighlighter); 

      // get line metrics and initialize highlight 
      metrics = textField.getLineMetrics(0); 
      setHighlighter(null); 
     } 

     private function setHighlighter (event:Event):void 
     { 
      var changed:Boolean = false; 

      // cache checks to make sure that the selection has changed 
      if (selectionBegin != textField.selectionBeginIndex) 
      { 
       selectionBegin = textField.selectionBeginIndex; 
       lineBegin = textField.getLineIndexOfChar(selectionBegin); 

       // when the caret is at the end of the text, getLineIndexOfChar will return -1 
       lineBegin = lineBegin != -1 ? lineBegin : textField.numLines - 1; 

       changed = true; 
      } 

      // same as above 
      if (selectionEnd != textField.selectionEndIndex) 
      { 
       selectionEnd = textField.selectionEndIndex; 
       lineEnd = textField.getLineIndexOfChar(selectionEnd); 
       lineEnd = lineEnd != -1 ? lineEnd : textField.numLines - 1; 
       changed = true; 
      } 

      // only move the highlight when something has changed 
      if (changed) 
      { 
       highlighter.y = textField.y + metrics.height * lineBegin + 2; 
       highlighter.height = textField.y + metrics.height * (lineEnd + 1) + 2 - highlighter.y; 
      } 
     } 
    } 
} 

您还可以看到Wonderfl这个解决方案,一个工作演示一起。

+0

非常有趣。感谢分享! – isyndicate 2012-11-06 05:23:24

1

假设您使用的是Spark组件,请定义一个textAreaFormat,并在其上设置backgroundColor属性。将格式应用于文本区域上的定义范围。

var textLayoutFormat:TextLayoutFormat = new TextLayoutFormat(); 
textLayoutFormat.fontSize = 12; 
textLayoutFormat.color = 0xFF0000; 
textLayoutFormat.backgroundColor = 0xFF00FF; 
myRET.setFormatOfRange(textLayoutFormat,begin,end); 
+0

我没有测试它,但是这不只是设置该行内的字符背景?所以如果文字环绕,不是整个文本字段的宽度是“突出显示”,对吧? – poke 2011-05-20 18:29:29

+0

将能够根据开始和结束锚定符来定义“选定文本”的格式。无可否认,不知道如何限制为由控件宽度定义的文本行。 – 2011-05-20 19:16:29