我正在尝试创建一个包含x按钮的通用列表控件,以便用户可以通过单击x按钮从列表中删除项目。但是,此列表控件需要支持项呈示器,同时仍然标准化放置在x按钮旁边的项目的布局。
所以我认为最好的方法是扩展列表控件并使用绘制x按钮的渲染器,并将其与用户提供的渲染器相结合。不幸的是我无法弄清楚如何做到这一点。
我尝试从IFactory接口覆盖newInstance方法并使用它来创建包含我的按钮的HBox并从用户提供的渲染器插入newInstance结果,但是它不完整。它显示为我所期望的,但鼠标悬停效果仅适用于用户提供的渲染器部分,而不是我的自定义渲染器制作的整个HBox。
关于此主题的Flex文档中似乎有很多缺失的细节。
我在Action Script 3中完成了所有这些。
答案 0 :(得分:4)
我不认为这样做的方法是扩展List控件。相反,我会尝试创建我的自定义itemRenderer,然后根据需要扩展它。实现这一目标的一种方法可以是:
编辑:添加了示例
这是一个简单的示例,说明如何创建一个扩展SkinnableComponent并实现IDataRenderer的itemRenderer。它支持2种状态,正常和悬停。请注意,在Flex中创建ItemRenderers非常昂贵,因此请始终尽量保持它们的轻量级。
package
{
import flash.events.MouseEvent;
import mx.core.IDataRenderer;
import spark.components.supportClasses.ButtonBase;
import spark.components.supportClasses.SkinnableComponent;
[SkinState("normal")]
[SkinState("hovered")]
public class LearningRenderer extends SkinnableComponent implements IDataRenderer
{
/** Define the skin parts. */
[SkinPart(required="true")]
public var deleteButton:ButtonBase;
public function LearningRenderer()
{
super();
// Set the skin class.
setStyle("skinClass", LearningRendererSkin);
// Add event listeners to support HOVERED.
addEventListener(MouseEvent.ROLL_OVER, rollOverHandler);
addEventListener(MouseEvent.ROLL_OUT, rollOutHandler);
}
/** Implement the partAdded() method. */
override protected function partAdded(partName:String, instance:Object):void
{
super.partAdded(partName, instance);
if(instance == deleteButton){
instance.addEventListener(MouseEvent.CLICK, button_clickHandler);
}
}
/** Implement the partRemoved() method. */
override protected function partRemoved(partName:String, instance:Object):void
{
if(instance == deleteButton){
instance.removeEventListener(MouseEvent.CLICK, button_clickHandler);
}
}
/** Implement the getCurrentSkinState() method. */
override protected function getCurrentSkinState():String
{
var returnState:String = "normal";
if (bRollOver)
returnState = "hovered";
return returnState;
}
public function get data():Object
{
return _data;
}
public function set data(value:Object):void
{
_data = value;
}
/** Add methods, properties, and metadata. */
private var _data:Object;
private var bRollOver:Boolean = false;
/**
* Handlers
*/
protected function button_clickHandler(eventObj:MouseEvent):void {
//Handle click
}
protected function rollOverHandler(eventObj:MouseEvent):void{
bRollOver = true;
invalidateSkinState();
}
protected function rollOutHandler(eventObj:MouseEvent):void{
bRollOver = false;
invalidateSkinState();
}
}
}
这是具有所需deleteButton的皮肤:
<?xml version="1.0" encoding="utf-8"?>
<s:Skin xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx">
<!-- host component -->
<fx:Metadata>
[HostComponent("LearningRenderer")]
</fx:Metadata>
<!-- states -->
<s:states>
<s:State name="normal" />
<s:State name="hovered" />
</s:states>
<s:Button id="deleteButton" label="Delete"/>
</s:Skin>
答案 1 :(得分:0)
首先 - 确保您使用的是Spark列表控件,而不是MX控件。众所周知,MX项目渲染器很难处理。相比之下,火花渲染表现相当好,易于处理。
现在......从这里开始Flex Quick Start - Using Spark Item Renderers。
最后 - 这里是关于如何Define a custom Spark Item Render的更深入的讨论。
我知道你说“我在ActionScript 3中制作了所有这些”(我认为这意味着你出于某种原因避免使用mxml)。 ...但是如果您正在使用列表控件和项呈示器,那么即使您没有使用MXML进行编码,也可以使用Flex框架。
因此,上述资源是适用的,无论是MXML还是纯AS3。请记住,每个MXML文档都对应于由mxml编译器生成的AS3类。 mxml文档的根xml标记告诉您生成的类将扩展到什么类。
因此,当您看到名为“MyRenderer.mxml”的mxml文件时,其内容如下所示:
<s:ItemRenderer>
...
</s:ItemRenderer>
你知道这对应于纯AS3类定义,如下所示:
class MyRenderer extends ItemRenderer {
...
}
在我看来 - 当你开始使用ItemRenderers并使用Spark(甚至是MX)组件时,MXML比纯粹的AS3更容易使用 。毕竟,框架组件是设计的,可以从mxml中使用。
祝你好运!答案 2 :(得分:0)
我发现最简单的解决方案是使用数据网格和最后一列的项呈示器。我扩展了高级数据网格以生成“EditabledList”类,并修改了“公共函数集列”方法以自动将我的删除按钮列添加到结尾。然后我为该列创建了一个删除按钮项呈示器。绑定点击操作有点棘手,因为我只引用了该行的数据,而不是对列表的引用。我通过覆盖“public set dataProvider”方法来解决这个问题,用我自己的自定义对象替换列表中的每个项目,该对象具有对列表的引用,唯一ID和“removeMe”方法。我将此对象称为EditableListItem。不幸的副作用是数据绑定必须以额外的“.data”作为前缀,因为用户的对象存储在我的EditableListItem的“data”属性中。
这就是我的渲染器的样子。
<fx:Component className="buttonRenderer">
<s:MXAdvancedDataGridItemRenderer height="100%" width="100%">
<s:Button left="5" top="5" skinClass="{buttonSkin}" click="EditableList.clickButton(data)"
useHandCursor="true" buttonMode="true" toolTip="Remove item"/>
</s:MXAdvancedDataGridItemRenderer>
</fx:Component>
buttonSkin刚刚渲染了具有翻转效果的自定义图像。