在很多自定义的组件中需要动态的计算字符串的实际宽度,如果字符串都是汉字那么可以利用String.length*汉字大小,但是在实际的应用中中英文相结合是很常见的事情。
案例如下:
<mx:TileList width="100%" height="100%" dataProvider="{chArr}" borderStyle="none" id="tl" columnWidth="100" > <mx:itemRenderer> <mx:Component> <mx:HBox horizontalAlign="left"> <mx:CheckBox selected="{data.select}" click="data.select=!data.select" label="{data.key}"/> </mx:HBox> </mx:Component> </mx:itemRenderer> </mx:TileList>
TileList 的数据源是动态的,因此每行显示的列数也是动态的,这就需要动态的计算columnWidth,
columnWidth=字符串所占最大实际宽度+其他组件的宽度。
笔者第一次计算的时候就犯了一个错误,首先计算出字符串所占得字节数,一个汉字占2个字节,然后总的字节数*字体大小。
计算一个字符串所占的字节数长度如下:
/** * 计算出双字节字符的长度 * 得到一个字符串的长度 一个汉字占2个字节 * @param sChars 字符串 * @return 字符串所占的长度 */ private function getStrActualLen(sChars:String):int{ return sChars.replace(/[^\x00-\xff]/g,"xx").length; }
以上算法如果都是汉字不会出现问题,如果都是英文就会出现字符串所占实际宽度大大小于columnWidth。
经过自己的一番研究,可以从flex的as3帮助文档中找到答案,flash.text.TextLineMetrics类负责测量字符串所占的实际宽度。
有关详细信息请自己参考API.
measureText(字符串)方法返回TextLineMetrics的实例,TextLineMetrics类的width返回字符串所占的实际宽度,Flex的显示组件一般都继承自UIComponent组件,UIComponent类含有measureText方法,因此可以直接使用this.measureText(字符串).
var maxStrLength:int=0;//最大宽度 for(var i:int=0;i<ac.length;i++){ var item:Object=ac.getItemAt(i); item.name= item[param.name]; var objLen:int=this.measureText(item.name).width; if(objLen>maxStrLength){ maxStrLength=objLen; } if(isFirst){ item.sel=false; } ac.setItemAt(item,i); }