代码之家  ›  专栏  ›  技术社区  ›  Dan

使flex数据报平滑滚动

  •  2
  • Dan  · 技术社区  · 15 年前

    我注意到,数据报垂直滚动条的默认行为是一次滚动一行。当行都是统一的和小的(例如,显示一行文本)时,这一切都很好,但当行的高度可变时,就会变得非常难看。

    我很好奇,有没有办法让数据报滚动“平滑”?例如,是否有一种方法可以让DataGrid按设置的像素数、文本行数等滚动,而不是一次滚动一行?

    到目前为止,我唯一能想到的解决方案是将数据报放在画布中,让画布代替数据报进行滚动。不过,这种方法的问题在于,一旦画布滚动到足够远的地方,DataGrid头就会从屏幕上滚动出来。理想情况下,我希望获得画布的平滑滚动性质,但也保持DataGrid头可见。有可能吗?

    2 回复  |  直到 9 年前
        1
  •  1
  •   RJ Owen    15 年前

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

    解决方法确实存在,尽管您注意到的方法(将数据报放到画布中)否定了项目呈现器保存显示对象的意图,并导致性能成本。这对于flex 4中大多数基于列表的flex组件都是固定的,但对于datagrid不会立即固定。DataGrid/AdvancedDataGrid组件由一个位于印度的独立团队维护,这是我上次听说的,因此它往往比SDK的其余部分落后一点。

    我建议你试试类似的 this implementation of a smooth-scrolling list by Alex Harui . 我不确定它在DataGrid或AdvancedDataGrid上的工作效果如何,但这是我能想到的使列表正确滚动的最直观的技术。

        2
  •  1
  •   Matt R.    15 年前

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

    亚历克斯最初的一些代码用于平滑的垂直滚动,但这不是我对数据报的问题。它是平滑的水平滚动,我需要。我以一种非常规的方式使用数据报来分析我们的数据库输出的纯文本报告(提供文档视觉反馈的好方法)。下面的代码允许内容离开屏幕,用户可以滚动,而不必执行该跳到列的行为。

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

    这个方法比上面链接中的亚历克斯的方法要简单一点——代码要少得多,所以尝试适应并看看它是如何工作的。

    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);
                }
            }
    
    推荐文章