关于ToolTip自定义其实自己一直有一些想法,因为通过自己的项目以及在别人的东西里面看到的,逐渐发现Flex默认提供的ToolTip并不是那么友好(这里说的友好是指用户的体验性),已然觉得有自定义ToolTip的必要了。
这几天利用空余的时间研究了下自定义ToolTip,现做一个小小的总结。自定义ToolTip有好方式,当就实现效果角度讲,我发现了3种,下面一一做介绍,重点介绍自己已经实现的方案。
1.仿照ToolTipManagerImpl并摒弃它的实现思路,自己实现、管理ToolTip.通过查看ToolTipManagerImpl的源码,发现它是
这样实现,因此我们可以仿照他自己操办ToolTip,需要注意的是,这种情况我们自己创建了ToolTip实例,所以实例的销货也要我们处理,一旦处理不好就会导致内存泄露,慎用!
2.实现IToolTip接口,并自定义它的border,实现带小箭头的ToolTip.它的精华部分是,通过border画出了小箭头,这种解决方案可能也是业界推崇的,我也从网上下了一些例子(这部分例子不贴出来了,有兴趣的自己下载),结果要么小箭头位置不合意,要么ToolTip的定位有问题。这才引发我思考第三中解决方案。
3.实现IToolTip接口,自己画小箭头。我这里说的自己画小箭头意思是指不通过border来做操作了,稍微注意的是在使用自定义ToolTip时,目标对象的toolTip属性一定要打开并设置成成toolTip=' ',具体操作不多说了,见代码。
测试主程序:CutomerTooltip
自定义的ToolTip类:PanelToolTip
static private const DIR_RIGHT:String = "right";
static private const DIR_LEFT:String = "left";
static private const DIR_UP:String = "up";
static private const DIR_DOWN:String = "down";
[Bindable]
public var bodyText:String = "";
public var dirFillColor:uint = 0x000000; //小尖角区域填充颜色,default:0x000000
public var dirFillAlpha:Number = 1; //小尖角区域填充alpha,default:1
public var dirOffsetY:int = 7; //小尖角距tooltip顶端的偏移量,default:7
public var distance_tip_tar:int = 10; //tooltip和target间的距离,default:10
public var distance_dir_twopoint_at_tip:int = 12; //在tooltip上的小尖角三角形的边长宽,default:12
private var _direction:Array; //顺序为x,y(right,left,up,down)
private var directionChange:Boolean;
private function set direction(value:Array):void {
_direction = value;
directionChange = true;
this.invalidateProperties();
}
// Implement required methods of the IToolTip interface;
public var _text:String;
[Bindable]
public function get text():String
{
return _text;
}
public function set text(value:String):void
{
}
private function init():void {
//只识别uint类型颜色,优先和border的颜色一样,若未设置boder的颜色,则采用默认填充色
var obj:uint = this.getStyle("borderColor") as uint;
if(obj){
dirFillColor = obj;
}
}
override protected function commitProperties():void {
super.commitProperties();
if(directionChange){
directionChange = false;
drawSharp();
}
}
//画小尖角
private function drawSharp():void {
var xdir:String = _direction[0] as String;
var ydir:String = _direction[1] as String;
var gr:Graphics = this.graphics;
gr.clear();
gr.beginFill(dirFillColor, dirFillAlpha);
if(xdir == DIR_RIGHT && ydir == DIR_DOWN){
/* gr.moveTo(0, 7);
gr.lineTo(-11, 13);
gr.lineTo(0, 19);
gr.moveTo(0, 7); */
gr.moveTo(0, dirOffsetY);
gr.lineTo(-distance_tip_tar-1, dirOffsetY+distance_dir_twopoint_at_tip/2);
gr.lineTo(0, dirOffsetY+distance_dir_twopoint_at_tip);
gr.moveTo(0, dirOffsetY);
}else if(xdir == DIR_RIGHT && ydir == DIR_UP){
gr.moveTo(0, 0 + this.height - dirOffsetY);
gr.lineTo(-distance_tip_tar -1, 0 + this.height - dirOffsetY-distance_dir_twopoint_at_tip/2);
gr.lineTo(0, 0 + this.height - dirOffsetY-distance_dir_twopoint_at_tip);
gr.moveTo(0, 0 + this.height - dirOffsetY);
}else if(xdir == DIR_LEFT && ydir == DIR_DOWN){
gr.moveTo(this.width, dirOffsetY);
gr.lineTo(this.width + distance_tip_tar + 1, dirOffsetY+distance_dir_twopoint_at_tip/2);
gr.lineTo(this.width, dirOffsetY+distance_dir_twopoint_at_tip);
gr.moveTo(this.width, dirOffsetY);
}else if(xdir == DIR_LEFT && ydir == DIR_UP){
gr.moveTo(this.width, this.height - dirOffsetY);
gr.lineTo(this.width + distance_tip_tar + 1, this.height - dirOffsetY-distance_dir_twopoint_at_tip/2);
gr.lineTo(this.width, this.height - dirOffsetY-distance_dir_twopoint_at_tip);
gr.moveTo(this.width, this.height - dirOffsetY);
}
gr.endFill();
}
/**
* @event:tooltip事件流
* @describe:重新定位tooltip,并为其画小尖角
* */
public function hasShownEventHandler(event:ToolTipEvent):void {
var target:UIComponent = event.currentTarget as UIComponent;
//只针对uicomponent做tooltip
if(!target){
return;
}
var tgPoint:Point = target.localToGlobal(new Point(0,0));
var resX:int = screen.width;
var resY:int = screen.height;
var realTX:int;
var realTY:int;
var toolRightX:int = tgPoint.x + target.width + distance_tip_tar;
var toolLeftX:int = tgPoint.x - distance_tip_tar - this.width;
var xchange:String = "";
//tooltip的定位优先右边,故先判断右边
if(toolRightX + this.width < resX){
// do right
xchange = PanelToolTip.DIR_RIGHT;
realTX = toolRightX
}else if(toolLeftX > 0){
// do left
xchange = PanelToolTip.DIR_LEFT;
realTX = toolLeftX;
}
var toolUpY:int = tgPoint.y + target.height;
var toolDownY:int = tgPoint.y;
var ychange:String = "";
//tooltip的定位优先下边,故先判断下边
if(toolDownY + this.height < resY){
//do down
ychange = PanelToolTip.DIR_DOWN;
realTY = toolDownY;
}else if(toolUpY - this.height > 0){
//do up
ychange = PanelToolTip.DIR_UP;
realTY = toolUpY - this.height;
}
//若不能定位tooltip的位置,则按默认tooltip的显示
if(xchange == "" || ychange == ""){
return;
}
//重新定位tooltip
this.x = realTX;
this.y = realTY;
this.direction = [xchange,ychange];
}
/**
* @title:tip的标题;
* @bodytxt:要tip的文字;
* @event:tootip事件流对象;
* @restrict:约束,即当bodytxt=''时,不创建tooltip,bodytxt!=''是才创建,default=true;
* @describe:传入相关参数,运用PanelToolTip创建自定义的tootip;
* */
static public function createCustomerTooltip(title:String,bodytxt:String,event:ToolTipEvent,restrict:Boolean=true):void {
if(restrict){
if(bodytxt == ""){
if(event.toolTip == null){
return;
}
}
}
var ptt:PanelToolTip = new PanelToolTip();
ptt.bodyText = bodytxt;
ptt.title = title;
event.toolTip = ptt;
}
/**
* @describe:存在两种情况:当tip的text!=''时,走正常流程,即执行第一个判断;当tip的text==''时,因为我们的tootip初始值为' ',
* 它已经产生了tooltip,但我们不想看到它,故将其的visible属性设置为false;注意下面的判断顺序不能变;
* */
static public function showCustomerTooltip(event:ToolTipEvent):void {
var ptt:PanelToolTip=event.toolTip as PanelToolTip;
if (ptt)
{
ptt.hasShownEventHandler(event);
}else if(event.toolTip && event.toolTip.parent != null)
{
event.toolTip.visible = false;
}
}
]]-->
</mx:Script>
<mx:Text text="{bodyText}"
percentWidth="100"/>
<mx:Image source="@Embed('jin.png')"
scaleContent="true"
scaleX="1"
scaleY=".5"/>
</mx:Panel>
效果: