今天发现一个问题,先详细描述一下我的需求:
- 显示一段文字,文字字数不定,但文本框长度有限,短于限制则完全显示,超过限制则截断只剩一行,并续以“…”
- 必须应对多语言环境,比如中文、英文、俄文等
我是这么计划的
- 因为多语种,每个语言的文字宽度可能都不一致,所以不太可能确定文本框的长度
- 于是创建一个里面有“…”的文本框缀在最后的做法可能就无效了
- 那么建立一个自动换行的文本框,利用Flash Player自己的渲染机制进行换行
- 取第一行的文字,连上”…”后再替换原来的文本
- 查阅手册,发现TextField有个方法叫getLineLength(index:int),取某行字数,遂决定采取此方案
写成代码后发现不行,代码大意如此(1):
var txt:TextField = new TextField(); txt.wordWrap = true; txt.text = '一段很长的文字,大约有100字吧'; txt.width = 240; // 期望长度 var length:int = txt.getLineLength(0); txt.text = txt.text.substr(0, length) + '...'; addChild(txt);
结果文本框比我预想的短很多,只有几个字,绝对不到240px。于是我开始各种调试,均无果,于是专门写了个这样子的测试用例(2)来测试:
var txt:TextField = new TextField(); txt.wordWrap = true; txt.text = '还是那段文字,总之很长'; addChild(txt); addEventListener(MouseEvent.CLICK, onClick); function onClick(evt:MouseEvent):void { txt.width = 100 + Math.random() * 100; trace(txt.getLineLength(0)); }
我惊讶发现这样做居然没问题了,这很灵异啊~
继续仔细观察,我发现(1)里的文字长度也有规律可循,长度似乎接近TextField默认的100px(TextField被创建为实例时,宽高均为100),于是我猜想:
Flash Player在处理文本时,出于效率考虑,不会随时根据代码来调整文字排版——据我所知文字排版消耗非常大——而是在添加到显示列表或每一帧结束时再做处理。
在(2)的onClick里复制一遍,就会发现,这个推论应该是真实的。
欢迎吐槽,共同进步