【问题标题】:Problems with itemRollOver and itemRollOut events on List componentList 组件上的 itemRollOver 和 itemRollOut 事件的问题
【发布时间】:2008-12-01 15:03:11
【问题描述】:

我已经在 List 组件上设置了 itemRollOveritemRollOut 事件侦听器,但是每当我将鼠标滚动到列表项上时,同一个列表项的 over 和 out 事件都会依次触发.我的列表使用自定义 itemRenderer。

任何想法为什么会这样? Adobe 文档没有提供对此的深入了解(不足为奇......)。

【问题讨论】:

    标签: apache-flex events flex3 adobe


    【解决方案1】:

    在我看来,这是一个错误。 ListBase.mouseOverHandler 现在在调度 ITEM_ROLL_OVER 事件时设置一个名为 lastHighlightItemRendererAtIndices 的变量,然后在调度 ListBase.clearHighlight(由 mouseOutHandler 调用)中的 ITEM_ROLL_OUT 事件时使用该变量(与 lastHighlightItemIndices 一起)。

    问题在于,当您逐行使用鼠标时,首先调用 mouseOverHandler,设置 lastHightlight... 变量,然后当随后调用 mouseOutHandler 时,它使用刚刚的 lastHighlight... 值设置为您获得同一渲染器的连续“翻转”和“推出”事件的结果。

    坦率地说,我不知道为什么 ListBase.clearHighlight 在调度 ITEM_ROLL_OUT 事件时不使用传入的渲染器(这是它在 SDK 2 中的工作方式),因为这是正在“滚动”的实际渲染器出'。

    【讨论】:

    • 很有趣,会解释这种行为。谁能证实这一点? (很遗憾,我现在没有时间深入研究 mx 代码。)
    【解决方案2】:

    它们来自同一个对象吗? 如果不是,您很可能会从刚刚离开的“项目”中获得 itemRollOut,从您输入的新项目中获得 itemRollOver,这取决于它们的间距,因此它们可能彼此非常接近。

    【讨论】:

    • 事件由同一个对象触发。对象不重叠,它们彼此相邻(中间为 0 像素)。
    【解决方案3】:

    如果要覆盖 set data(),请确保在项目渲染器中设置 super.data

    ListBase 监听 MOUSE_OVER,然后根据鼠标的坐标和项目渲染器的位置找出它下面的项目。您可以检查 ListEvent.itemRenderer 以查看哪个渲染器的翻转和滚动正在触发以及以什么顺序触发。

    最坏的情况,您可以在项目渲染器中监听 rollOver 和 rollOut。

    【讨论】:

      【解决方案4】:

      遇到了同样的问题。 super.data 已经被设置,并且该项目对于 rollOut 和 rollOver 事件是相同的。我最终选择了 anirudhsasikumar 的最坏情况,并在项目渲染器中监听了 rollOver 和 rollOut。似乎工作正常。

      【讨论】:

        【解决方案5】:

        我遇到了同样的问题。我最终继承了 mx.controls.List 类并覆盖了 clearHighlight 函数。据我所知,lastHighlightItemIndices 变量只能在该函数中读取。因此,执行以下操作可以解决此问题:

        import mx.core.mx_internal;
        
        use namespace mx_internal;
        
        public class List extends mx.controls.List
        {
            public function List()
            {
                super();
            }
        
            override mx_internal function clearHighlight( item:IListItemRenderer ):void
            {
                var uid:String = itemToUID( item.data );
        
                drawItem( UIDToItemRenderer( uid ), isItemSelected( item.data ), false, uid == caretUID );
        
                var pt:Point = itemRendererToIndices( item );
        
                if( pt )
                {
                    var listEvent:ListEvent = new ListEvent( ListEvent.ITEM_ROLL_OUT );
        
                    listEvent.columnIndex = item.x;
                    listEvent.rowIndex = item.y;
                    listEvent.itemRenderer = item;
        
                    dispatchEvent( listEvent );
                }
            }
        }
        

        然后只需使用这个 List 类而不是 Adob​​e 类,你就会得到你所期望的行为。我针对 Flex SDK 3.2 进行了测试,它可以工作。

        <mx:Canvas xmlns:mx="http://www.adobe.com/2006/mxml" xmlns:controls="com.example.controls.*">
        
            [ other code ... ]
        
            <controls:List itemRollOver="onItemRollOver( event )" itemRollOut="onItemRollOut( event )" />
        
        </mx:Canvas>
        

        感谢 Gino Basso 在上面的帖子中提出的想法。希望对您有所帮助。

        【讨论】:

        • 感谢您的提示。当我回到有问题的项目时,我会尝试一下!
        【解决方案6】:

        感谢您的解决方案。这真的解决了问题!不过小幅修正:

        listEvent.columnIndex = item.x;
        listEvent.rowIndex = item.y;
        

        应该是

        listEvent.columnIndex = pt.x;
        listEvent.rowIndex = pt.y;
        

        item.x 和 y 以像素为单位保存渲染器的坐标。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2010-11-13
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-02-02
          • 2011-04-11
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多