3 Star 44 Fork 10

Ryan Zhu / OhosExtension

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
ScrollApiHelper.md 2.80 KB
一键复制 编辑 原始数据 按行查看 历史

ScrollApiHelper

由于鸿蒙中普通控件与布局的scrollBy、scrollTo函数不生效,因此使用此类帮助控件滚动

使用

ScrollApiHelper scrollApiHelper = new ScrollApiHelper(this);

// 滚动
scrollApiHelper.scrollTo(x, y);
scrollApiHelper.scrollBy(deltaX, deltaY);

// 获取当前的滚动距离
scrollApiHelper.getScrollX();
scrollApiHelper.getScrollY();

// 设置滚动边界
scrollApiHelper.setScrollRangeX();
scrollApiHelper.setScrollRangeY();

// 如果想要scroll到负数
scrollApiHelper.setMinScrollRangeX(-100);
scrollApiHelper.setMinScrollRangeY(-100);

原理

通过将该控件的所有child通过setComponentPosition改变位置,达到整体滚动的效果。

  • child的top:子控件的初始top + scrollY
  • child的left:子控件的初始left + scrollX

scrollApiHelper会缓存所有child的初始位置信息,并于当前的滚动距离相加,计算得出child的新的top或者left并设置进去。

注意

由于是通过setComponentPosition来实现的滚动,因此获取child的top、left、right、bottom等会出现数值不是预期的情况,真实的值应该是:

  • top: Component.getTop + ScrollApiHelper.getScrollY
  • left: Component.getLeft + ScrollApiHelper.getScrollX
  • right: Component.getRight + ScrollApiHelper.getScrollX
  • bottom: Component.getBottom + ScrollApiHelper.getScrollY

关于onArrange

由于是使用setComponentPosition来实现滚动,而非控件内的scroll来实现,因此在控件发生重新布局后,滚动会跳到最顶部。这是因为onArrange会把所有子控件的位置还原。

如果我们自定义了控件,并且确定在滚动途中会发生重新布局,或者调用了postLayout或者invalidate函数,那么我们可以通过在onArrange内,将child的top或者left加上我们当前的滚动距离,就可以达到滚动不往顶部跳的目的。

但是这样会产生另外一个问题就是滚动值的计算会出现问题,因为所有child的初始top或者left已经发生了改变。这时我们需要为ScrollApiHelper设置一个偏移量,来中和初始top或者left的改变,并且重新缓存child的位置信息。

即在onArrange内:

  1. 将child的top或者left加上我们当前的滚动距离
  2. 为ScrollApiHelper设置一个偏移量,值为当前的滚动距离
  3. 重新缓存child的位置信息

以垂直方向滚动举例(不完整代码):

@Override
public boolean onArrange(int l, int t, int width, int height) {
    int childTop;
    int scrollY = scrollApiHelper.getScrollY();
    for(...) {
        int childHeight = child.getEstimatedHeight();
        child.arrange(0, childTop + scrollY, child.getEstimatedWidth(), childHeight);
        childTop += childHeight;
    }

    scrollApiHelper.resetSavedPositions();
    scrollApiHelper.setOffsetToScrollY(scrollY);
}
Java
1
https://gitee.com/thoseyears/ohos-extension.git
git@gitee.com:thoseyears/ohos-extension.git
thoseyears
ohos-extension
OhosExtension
master

搜索帮助