相信使用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国外人写好的一个(关键要看,回贴内容)
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 );
}
}
运行效果图: