`
#天琪#
  • 浏览: 155828 次
  • 性别: Icon_minigender_2
  • 来自: 长沙
社区版块
存档分类
最新评论

Flex中对文本实现高亮显示

    博客分类:
  • FLEX
阅读更多
转自http://blog.minidx.com/2008/07/28/1178.html
去原处看吧,这篇里面没图,不好理解~~~

如何确定高亮块的位置及高宽是本文的重点。我们可以灵活运用TextField类的几个方法得到相关的数值:

1.getLineIndexOfChar(charIndex:int):int

Returns the zero-based index value of the line containing the character specified by the charIndex parameter.

2.getLineOffset(lineIndex:int):int

Returns the character index of the first character in the line that the lineIndex parameter specifies.

3.getLineLength(lineIndex:int):int

Returns the number of characters in a specific text line.

4.getLineIndexOfChar(charIndex:int):int

Returns the zero-based index value of the line containing the character specified by the charIndex parameter.

5.getCharBoundaries(charIndex:int):Rectangle

Returns a rectangle that is the bounding box of the character.

此外,我们再来看幅图片,了解一下Flash文本的结构:

“2-pixel gutter”这个要特别注意,若忘记加到位置计算公式中,高亮块会发生2像素的偏移.

现在来考虑下高亮块出现的几个位置(本例文本排列均限定为从左至右):

1.选定文本块在TextField显示区的所有行外



这种情况可以不处理.

2. 选定文本块在TextField显示区内





将选定文本块分划为多个”单行”处理:

首行高亮的区间为beginIndex至首行结束字符;

中间高亮的区间均为行首至行尾;

尾行高亮的区间为行首至endIndex.

3. 选定文本块一部分在显示区内,一部分在显示区外。分两种情况:

1) 起始索引小于显示区第一个字符的索引值,只需在下图中beginIndex至endIndex之间绘制高亮



2) 结束索引大于显示区最后一个字符的索引值,只需在下图中beginIndex至endIndex之间绘制高亮

 

总结如下:

1.获得有效的起始索引及结束索引;

2.如果为单行高亮块,进行单行绘制;

3.如果为多行高亮块,依次进行首行,中间行,尾行的绘制

基本方法确定后,我们在FLEX BUILDER 3中新建项目”HighlightTest”,



新建文件夹com->kingnare->regex

在regex文件夹中新建类HighlightBlock, superclass选择UIMovieClip.



根据前面的思路,我们写出HighlightBlock类:

HighlightBlock.as

简单描述一下HighlightBlock的流程:

通过getValidBeginCharIndex和getValidEndCharIndex方法得到高亮块在显示区的起始及结束索引,之后调用normalDraw绘制高亮块.

在normalDraw方法中,通过getDisLineHeightByLine得到输入索引值所在的行相对于文本注册点的距离,便于计算出高亮块的y坐标.

那么怎么使用这个类呢?

我们的接入参数类型是IUITextField,但TextArea等组件的内部文本均为protected,要通过继承来访问.我们新建文件com->components,在components文件夹中新建BlockTextArea类,superclass选择TextArea:



代码如下:

package com.components
{
import com.kingnare.regex.HighlightBlock;
import flash.display.DisplayObject;
import flash.geom.Point;
import mx.controls.TextArea;
 
public class BlockTextArea extends TextArea
{
private var blockArray:Array;
 
public function BlockTextArea()
{
super();
blockArray = [];
}
 
public function showBlock(beginIndex:int, endIndex:int):void
{
var movieTip:HighlightBlock= new HighlightBlock(this.textField);
 
movieTip.offsetPoint = new Point(0, 0);
movieTip.highLightDraw(beginIndex, endIndex);
movieTip.toolTip = “beginIndex: “+beginIndex+“\nendIndex: “+endIndex+“\nlength: “+(endIndex-beginIndex+1).toString()+“\ntext:\t”+this.textField.text.substring(beginIndex, endIndex+1);
clearBlock();
this.addChild(movieTip);
blockArray.push(movieTip);
}
 
public function clearBlock():void
{
var len:uint = blockArray.length;
 
for(var k:uint=0;k<len;k++)
{
var obj:DisplayObject = blockArray[k]
this.removeChild(obj);
obj = null;
}
blockArray = [];
}
}
}
切换到HighlightTest.mxml,设置主程序高宽为160×420,并添加一个BlockTextArea组件.

之后再加入其他控件:

<components:BlockTextArea id=”lightText” width=”400″ height=”100″ y=”10″ x=”10″/>
<mx:Button y=”118″ label=”Show Highlight” right=”10″/>
<mx:TextInput id=”beginIndexInput” x=”92″ y=”118″ width=”60″/>
<mx:TextInput id=”endIndexInput” x=”232″ y=”118″ width=”60″/>
<mx:Label x=”10″ y=”121″ text=”beginIndex:”/>
<mx:Label x=”160″ y=”121″ text=”endIndex:”/>
切换到Design panel:



接下来为主程序加入ActionScript代码.

首先是Application的applicationComplete事件:

<mx:Application xmlns:mx=”http://www.adobe.com/2006/mxml” layout=”absolute” xmlns:components=”com.components.*”
width=”420″ height=”160″ applicationComplete=”initApp();”>
然后在ActionScript块中编写initApp方法:

private function initApp():void
{
}
在这个方法里我们初始化lightText,beginIndexInput,endIndexInput的文本,并加入lightText的ScrollEvent事件的Listener:

import mx.events.ScrollEvent;
import mx.managers.ToolTipManager;
 
private function initApp():void
{
//ToolTip立即显示
ToolTipManager.showDelay = 0;
lightText.addEventListener(ScrollEvent.SCROLL, scrollEvent);
lightText.htmlText = “Documentation for classes includes syntax, “ +
“<b><font size=’18′>usage</font></b> information, and code samples for methods, “ +
“properties, “ +
“and event handlers and listeners for those APIs that belong to a specific class “ +
“in ActionScript (as opposed to global functions or properties). “ +
“The <font size=’24′>classes</font> are listed alphabetically. “ +
“If you are not sure to which class a certain method or property belongs, “ +
“you can look it up in the Index.”;
beginIndexInput.text = “43″;
endIndexInput.text = “300″;
}
再完成”show highlight”按钮的点击方法即高亮显示方法:

private function showBlock():void
{
lightText.showBlock(parseInt(beginIndexInput.text), parseInt(endIndexInput.text));
}
为了及时更新高亮块,我们还要加入一个计时器,当文本发生变化时调用showBlock重绘高亮块.最终主程序代码如下:

<?xml version=”1.0″ encoding=”utf-8″?>
<mx:Application xmlns:mx=”http://www.adobe.com/2006/mxml” layout=”absolute” xmlns:components=”com.components.*”
width=”420″ height=”160″ applicationComplete=”initApp();”>
<mx:Script>
 
<![CDATA[
 
import mx.events.ScrollEvent;
import mx.managers.ToolTipManager;
private var updateTimer:Timer;
 
private function initApp():void
{
ToolTipManager.showDelay = 0;
 
//timer
updateTimer = new Timer(5, 1);
updateTimer.addEventListener(TimerEvent.TIMER, validate, false, 0, true);
lightText.addEventListener(ScrollEvent.SCROLL, scrollEvent);
 
lightText.htmlText = "Documentation for classes includes syntax, " +
"<b><font size='18'>usage</font></b> information, and code samples for methods, " +
"properties, " +
"and event handlers and listeners for those APIs that belong to a specific class " +
"in ActionScript (as opposed to global functions or properties). " +
"The <font size='24'>classes</font> are listed alphabetically. " +
"If you are not sure to which class a certain method or property belongs, " +
"you can look it up in the Index.";
 
beginIndexInput.text = "43";
endIndexInput.text = "300";
}
 
private function showBlock():void
{
lightText.showBlock(parseInt(beginIndexInput.text), parseInt(endIndexInput.text));
}
 
//validate
private function validate(event:TimerEvent):void
{
showBlock();
}
 
//scrollEvent
private function scrollEvent(event:ScrollEvent):void
{
updateBlock();
}
 
//更新
private function updateBlock():void
{
updateTimer.reset();
updateTimer.start();
}
]]>
 
</mx:Script>
 
<components:BlockTextArea id=”lightText” width=”400″ height=”100″ y=”10″ x=”10″/>
<mx:Button y=”118″ label=”Show Highlight” click=”showBlock();” right=”10″/>
<mx:TextInput id=”beginIndexInput” x=”92″ y=”118″ width=”60″/>
<mx:TextInput id=”endIndexInput” x=”232″ y=”118″ width=”60″/>
<mx:Label x=”10″ y=”121″ text=”beginIndex:”/>
<mx:Label x=”160″ y=”121″ text=”endIndex:”/>
 
</mx:Application>
然后我们开始测试.点击”Debug”按钮:



点击”Show Highlight”按钮,可以看到绘制出的淡蓝色高亮块:



滚动条滚动时会调用updateBlock方法,在5ms后调用showBlock方法重绘高亮块:



(如果beginIndex小于0或endIndex大于等于文本长度,或者endIndex小于beginIndex均不会显示高亮块)

如果认为这种显示方式过于死板,你可以更改HighlightBlock类的drawBlock方法,或者继承HighlightBlock类重写drawBlock方法,做出诸如波浪线,下划线等效果.

如果将HighlightBlock类的_textField类型由IUITextField更换为TextField并做相关改动,HighlightBlock类也可用于ActionScript Project.

分享到:
评论
1 楼 wenqihui2008 2009-08-17  
不错,好东西,正需要。谢谢。只是以标记的文字不能选了。我想要就是一篇阅读理解中作标记那种,不知lz可否有提示一下。

相关推荐

Global site tag (gtag.js) - Google Analytics