相信使用Starling开发的,在使用TextField时,会遇到,超链接文件功能不可用的问题;
看一下源码;就知道,毕竟他是在原生的TextField基础上实现的,将TextField draw成Texture然后放到GPU显示;
如果要实现链接功能;
那么有个思路:
1)、获取:超链接文本的显示内容;
2)、获取:超链接文件的链接内容;
3)、使用原生的TextField,计算,第1)点中的,所有显示内容的字符;并计算该所有字符的有效矩形区域;(在Touch或是Mouse交互时,作坐标与矩形区域判断);
生成类型这样的数据结构,作为触发Link事件数据对象;
如:var data:Object = {rects:Vector.<Rectangle>, linkTxt:第2)点的链接内容}
这样在加上,Touch事件,判断Touch的End阶段事件,的x,y位置是否与上面的:rects有交集,有则触发事件,并将:linkTxt数据传过事件对象中即可;
下面给出一个GitHub国外人写好的一个(关键要看,回贴内容)
Textfields with hyperlinks
其中有个回贴有提供实现的另一种方式
Jave特别提示:Textfield width hyperlinks中的rects都union在一起,该方法最好还是不要联合一起,特别是对那些链接内容遇到换行时,那么矩形区域就会变得不准确;
自己写了个测试程序:
以下实现方式,我没写使用矩形与交互点的碰撞检测方式;
也是使用了,国外代码的写方,直接使用一个可交互的对象:Sprite
如果要使用矩形方式,那些就得对所有的rect都遍历并碰撞检测试;
如果要优化,还可以使用,四叉树,对矩形的合理分布区域,再做高交的选择性检测;
主要代码:
package { import flash.display.Sprite; import flash.display.StageAlign; import flash.display.StageScaleMode; import flash.filters.GlowFilter; import flash.geom.Rectangle; import flash.text.TextField; import flash.text.TextFieldAutoSize; import flash.text.TextFormat; /** * 测试TextField超链接内容自定义的热区交互方式 * @author Jave.Lin * @date 2013-9-29 **/ [SWF(width="1000", height="600")] public class RegexpTestingProject extends Sprite { private var tf:TextField; private var txt:String = "<a href='event:test'>测试</a>一下,这是带链接的文件信息,<a href='event:on link click event'>点击这里</a>,就可以超链接到<a href='event:http://www.baidu.com'>百度</a>"; private var hrefRegexp:RegExp = /<a.*?href=[""'](?<url>.*?)[""'].*?>(?<name>.*?)<\/a>|<(.|\n)*?>/g; private var hotAreaSpArr:Array = []; public function RegexpTestingProject() { stage.color = 0x888888; stage.frameRate = 60; stage.align = StageAlign.TOP_LEFT; stage.scaleMode = StageScaleMode.NO_SCALE; tf = new TextField(); tf.x = 100; tf.y = 100; tf.autoSize = TextFieldAutoSize.LEFT; var format:TextFormat = tf.defaultTextFormat; format.color = 0xffffff; tf.defaultTextFormat = format; tf.setTextFormat(format); tf.filters = [new GlowFilter(0, 1, 1.2, 1.2, 10)]; tf.htmlText = txt; tf.mouseEnabled = false; addChild(tf); // 刷新超链接热区 refreshLinkHotArea(); } private function refreshLinkHotArea():void { hotAreaSpArr.length = 0; var result:Object; var hrefsIndx:int; while((result = hrefRegexp.exec(txt)) !== null) { const tag:String = String(result[0]); const tagLength:int = tag.length; const href:String = String(result[1]); const value:String = String(result[2]); trace("href = " + href + " value = " + value); const data:Object = {href:href, value:value}; var sIdx:int = result.index - hrefsIndx; var eIdx:int = sIdx + value.length; var rect:Rectangle; for (var i:int = sIdx; i < eIdx; i++) { rect = tf.getCharBoundaries(i); if(!rect) continue; // var key:String = toKey(rect); // trace("key = " + key); var hotArea:LinkHotArea = new LinkHotArea(rect, data); hotArea.x = tf.x + rect.x; hotArea.y = tf.y + rect.y; addChild(hotArea); hotAreaSpArr.push(hotArea); } hrefsIndx += tag.length - value.length; } } public static function toKey(rect:Rectangle):String { var keyArr:Array = [ rect.x, rect.y, rect.width, rect.height ]; var key:String = keyArr.join("_"); return key; } } } import flash.display.Sprite; import flash.events.MouseEvent; import flash.geom.Rectangle; class LinkHotArea extends Sprite { public var data:Object; public var rect:Rectangle; public function LinkHotArea(rect:Rectangle, data:Object) { this.rect = rect; this.data = data; this.graphics.beginFill(0x00ff00, .5);//0);//.5);//这里换成.5,即可看到热区的位置,大小 this.graphics.drawRect(0, 0, rect.width, rect.height); this.graphics.endFill(); buttonMode = true; addEventListener(MouseEvent.CLICK, onClick); } private function onClick(e:MouseEvent):void { var rectKey:String = RegexpTestingProject.toKey(rect); var dataStr:String = ""; for (var key:String in data) { dataStr += key + " = " + data[key] + ", "; } trace("LinkHotArea trigger : rectKey = " + rectKey + ", " + dataStr ); } }