使Flex DataGrid滚动顺利

时间:2009-12-02 18:36:36

标签: flex actionscript-3 mxml

我注意到DataGrid的垂直滚动条的默认行为是一次滚动一行。当行完全均匀且很小(例如显示单行文本)时,这一切都很好,但是只要行具有可变高度的行就会变得非常难看。

我很好奇,有没有办法让DataGrid滚动“流畅”?例如,有没有办法让DataGrid按一定数量的像素,文本行等滚动,而不是一次滚动一行?

到目前为止,我设法提出的唯一解决方案是将DataGrid放在Canvas中,让Canvas进行滚动而不是DataGrid。但是,这种方法的问题是,只要Canvas滚动得足够远,DataGrid标题就会滚动到屏幕外。理想情况下,我希望获得Canvas的平滑滚动特性,同时保持DataGrid标头可见。这可能吗?

2 个答案:

答案 0 :(得分:1)

ItemRenderer在Flex 3中的工作方式使得平滑滚动难以实现。基本上,Flex回收从列表顶部滚动的项目渲染器,作为用于列表底部的新数据的显示对象。 Adobe在Flex 3中实现大多数列表组件会创建并添加这些项目,因为它们会出现在屏幕上,而不仅仅是屏幕外,因此它们会“弹出”并且无法进行平滑滚动。我不确定为什么他们不能以类似的方式对当前滚动窗格上方或下方的项目+/-一个位置进行操作,但他们没有,并且默认情况下我们坚持使用粘性滚动。 / p>

确实存在解决方法,尽管您已经注意到了(将数据网格放入画布中)否定了项目渲染器的显示对象节省意图并导致性能成本。对于Flex 4中的大多数基于列表的Flex组件,这将得到修复,但不会立即为DataGrid修复。我听说,DataGrid / AdvancedDataGrid组件由印度的一个独立团队维护,因此它往往落后于SDK的其余部分。

我建议您尝试类似this implementation of a smooth-scrolling list by Alex Harui的内容。我不确定它对DataGrid或AdvancedDataGrid的效果有多好,但这是我能想到的最直观的技术,可以使列表正确滚动。

答案 1 :(得分:1)

试试这个......它仍然基于上面提到的Alex的代码。他应该仍然是一个很好的开始,可以消除对齐行为。原始来源: http://blogs.adobe.com/aharui/2008/03/smooth_scrolling_list.html

Alex最初的一些代码用于平滑垂直滚动,但这不是我对DataGrid的问题。我需要水平平滑滚动。我正在以非正统的方式使用DataGrid来分析我们的数据库输出的纯文本报告(提供文档视觉反馈的好方法)。下面的代码允许内容离开屏幕,用户可以滚动而不会出现按行到列的行为。

您可以对此进行调整以使用相同的数学例程进行垂直滚动,然后它将使滚动成为可能并忽略对齐行的行为。特别是切换listContent.move方法的用法来垂直移动内容,并使用从垂直滚动条计算的圆角像素值的倒数(而不是我使用水平)。

这个方法比上面链接中的Alex方法简单一点 - 代码少得多,所以尝试调整并看看它是如何工作的。

override protected function scrollHandler(event:Event):void
        {           
            // Override the default scroll behavior to provide smooth horizontal scrolling and not the usual "snap-to-column" behavior
            var scrEvt:ScrollEvent = event as ScrollEvent;
            if(scrEvt.direction == ScrollEventDirection.HORIZONTAL) {
                // Get individual components of a scroll bar for measuring and get a horizontal position to use
                var scrDownArrow:DisplayObject = horizontalScrollBar.getChildAt(3);
                var sctThumb:DisplayObject = horizontalScrollBar.getChildAt(2);     
                // I replaced maxHorizontalScrollPosition in Alex's code with "1300" to fix my exact application. In other situations you may finding using some property or different value is more appropriate. Don't rely on my choice.
                var hPos:Number = Math.round((sctThumb.y - scrDownArrow.height) / (scrDownArrow.y - sctThumb.height - scrDownArrow.height) * 1300);     

                // Inverse the position to scroll the content to the left for large reports
                listContent.move(hPos * -1, listContent.y);
            }
            // Go ahead and use the default handler for vertical scrolling
            else {
                super.scrollHandler(event);
            }
        }