首页 > 设计 > WEB开发 > 正文

7.9.为渲染器设置高效图像

2023-08-02 23:09:29
字体:
来源:转载
供稿:网友
7.9.1.问题
你需要在通过data 把图片传入itemRenderer 里并显示图片。
7.9.2.解决办法
创建一个新的renderer 类,并且利用commitProperties 方法和owner 属性可以完成这些工作。我们可以在renderer 拥有者所在的文件里定义一个方法,用于返回我们要图示的图片。
7.9.3.讨论
List 和ListBase 的设计者Alex Harui,在自己的blog 里写到:“你可以把Image 标签放到Canvas 里,但这不是一个最好的方式。”为什么?因为Flex 框架为了简化我的开发,通过大量很复杂的操作来计算组件的大小,并且在刷新子组件和刷新自己时,都会再做这些复杂的操作。也就是说,我们可以多做一些事情,从而减轻框架的工作,这样就可以为FlashPlayer 减少很多不必要的负担。

本例中的renderer 实现了IListItemRenderer 和IDropInListItemRenderer 接口。因为这个组件继承了UIComponent,我们需要重写measure 方法这样我们就可以指定组件的明确大小。你需要通过实现measure,测量出image 的大小,并赋值给组件的measuredWidth和measuredHeight。

还有另一种方式,renderer 通过访问它的父组件,从而得到Image class,值得注意的是这种方式中,image 并没有传到renderer 中。在我们的例子中,renderer 通过data 访问父组件,从而得到内嵌image 的引用。
+展开
-ActionScript
if(listData) {
// remove the old child if we have one
if(img) {
removeChild(img);
}
if(_imgClass == null) {
var _imgClass:Class =UIComponent(owner).document[listData.label];
}
img = new _imgClass();
addChild(img);
}

访问父组件可以通过owner 的document,然后结合listData 确定要访问父组件的,哪个方法或属性。这样,我们即可以用传入的image 也可以直接去父组件里取image。下面是renderer 的代码:
+展开
-ActionScript
package oreilly.cookbook {
import flash.display.DisplayObject;
import mx.events.FlexEvent;
import mx.controls.listClasses.BaseListData;
import mx.controls.listClasses.IDropInListItemRenderer;
import mx.controls.listClasses.IListItemRenderer;
import mx.core.UIComponent;
public class SevenSixRenderer extends UIComponent implements IDropInListItemRenderer, IListItemRenderer {
private var _data:Object;
private var img:DisplayObject;
private var _listData:BaseListData;
private var _imgClass:Class;
[Bindable("dataChange")]
public function get data():Object {return _data;}
public function set data(value:Object):void {
_data = value;
if(_data.imgClass != null) {
_imgClass =_data.imgClass;
}
invalidateProperties(); // invalidate properties so that we'recertainthatthey'll be updated.
dispatchEvent(new FlexEvent(FlexEvent.DATA_CHANGE));
}
[Bindable("dataChange")]
public function get listData():BaseListData { return _listData; }
public function set listData(value:BaseListData):void { _listData = value; }
override protected function commitProperties():void {
super.commitProperties();
// sometimes the listdata of the renderer can be null, in which case we
//certainly don't
// want to throw runtime errors
if (listData) {
// remove the old child if we have one
if (img) {
removeChild(img);
}
if (_imgClass == null ) {
var _imgClass:Class = UIComponent(owner).document[ listData.label];
}
img = new _imgClass();
addChild(img);
}
}
/* create the image instance now that we know what it is */
override protected function measure():void {
super.measure();
if (img) {
measuredHeight = img.height;
measuredWidth = img.width;
}
}
/* make sure the image is positioned correctly */
override protected function updateDisplayList(w:Number,h:Number):void{
super.updateDisplayList(w, h);
if (img) { img.x = (w - img.width) / 2;
}
}
}
}

在上边的代码中我们重写了commitProperties,如果传入的Image 为null,我们就利用owner 去调用DataGridColumn 的labelFunction 方法,得到一个默认的Image,如果传入的Image 不为null,则直接利用传入的Image。
+展开
-XML
<mx:HBox xmlns:mx="http://www.adobe.com/2006/mxmlwidth="700"
height="300">

<mx:Script>
<![CDATA[
import mx.collections.ArrayCollection;
[Embed(source="../assets/foo.jpeg")]
private var img:Class;
[Embed(source="../assets/bar.jpeg")]
public var img2:Class;
//just a generic collection to store some plain old info
[Bindable]
private var genericCollectionOne:ArrayCollection = new ArrayCollection([{name:"josh noble"
, age:30, appearance:"Somewhat wild"},{name:"Abey George", age:32, appearance:"Pretty tight", imgClass:img},{name:"Todd Anderson", age:31,appearance:"Intimidating"},{name:"Ryan
Taylor", age:25, appearance:"Boyishly Handsome", imgClass:img},{name:"Steve Weiss", age:36, appearance:"George Clooney-ish"}]);
// for our itemRenderer we use the call into this method if the imgClass
//property is null
private function getImage(o:Object, c:DataGridColumn):String { return "img2";}

]]>
</mx:Script>
<mx:DataGrid dataProvider="{genericCollectionOne}">
<mx:columns>
<mx:DataGridColumn dataField="age"/>
<mx:DataGridColumn dataField="name"/>
<mx:DataGridColumn dataField="appearance"/>
<mx:DataGridColumn
itemRenderer="oreilly.cookbook.SevenSixRenderer"
labelFunction="getImage dataField="imgClass"/>

</mx:columns>
</mx:DataGrid>
</mx:HBox>
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表