3 Star 44 Fork 10

Ryan Zhu / OhosExtension

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
ScrollHelper.md 4.99 KB
一键复制 编辑 原始数据 按行查看 历史
朱帆 提交于 2021-07-23 11:05 . update readme

ScrollHelper

由于在ohos中,我们无法重写系统控件的触摸事件,只能通过setTouchListener来设置一个回调,这意味着我们无法侵入到ohos系统控件原有的滚动处理逻辑内。因此我们如果需要实现NestedScrollingChild接口,就需要重写控件的滚动逻辑。

ScrollHelper类封装了一套比较通用的滚动处理逻辑,并且内部维护了NestedScrollingChildHelper实例对象,自定义控件只需要实现ScrollingView与NestedScrollingChild等接口,并转发NestedScrollingChild中的函数至ScrollHelper的同名函数即可重写滚动逻辑。

注意:ScrollHelper仅仅处理滚动相关的逻辑,比如事件分发、触摸事件处理、嵌套滚动,其主要作用是帮助现有的可滚动的组件实现嵌套滚动。如果想要实现滚动本身,可以借助ScrollApiHelper

使用

  1. 实现ViewGroup、ScrollingView与NestedScrollingChild接口
public class NestedListContainer extends ListContainer
        implements Component.TouchEventListener, ViewGroup,
        NestedScrollingChild, ScrollingView 
  1. 初始化ScrollHelper
private final ScrollHelper helper;
helper = new ScrollHelper(this);
  1. 设置setTouchEventListener,并转发ohos的onTouchEvent至ScrollHelper中
setTouchEventListener(this);

@Override
public boolean onTouchEvent(Component component, TouchEvent ev) {
    return helper.onTouchEvent(component, ev);
}
  1. 转发ViewGroup接口至ScrollHelper的同名函数中:
    // ViewGroup

    @Override
    public void requestDisallowInterceptTouchEvent(boolean disallowIntercept) {
        helper.requestDisallowInterceptTouchEvent(disallowIntercept);
    }

    @Override
    public boolean onInterceptTouchEvent(TouchEvent ev) {
        return helper.onInterceptTouchEvent(ev);
    }

    @Override
    public boolean dispatchTouchEvent(TouchEvent ev) {
        return helper.dispatchTouchEvent(ev);
    }

    @Override
    public boolean onTouchEvent(TouchEvent ev) {
        return helper.onTouchEvent(ev);
    }

    @Override
    public boolean isConsumed() {
        return helper.isConsumed();
    }
  1. 转发NestedScrollingChild至ScrollHelper的同名函数中:
    // NestedScrollingChild

    @Override
    public void setNestedScrollingEnabled(boolean enabled) {
        helper.setNestedScrollingEnabled(enabled);
    }

    @Override
    public boolean isNestedScrollingEnabled() {
        return helper.isNestedScrollingEnabled();
    }

    @Override
    public boolean startNestedScroll(int axes, int type) {
        return helper.startNestedScroll(axes, type);
    }

    @Override
    public void stopNestedScroll(int type) {
        helper.stopNestedScroll(type);
    }

    @Override
    public boolean hasNestedScrollingParent(int type) {
        return helper.hasNestedScrollingParent(type);
    }

    @Override
    public boolean dispatchNestedScroll(int dxConsumed, int dyConsumed, int dxUnconsumed, int dyUnconsumed, int[] offsetInWindow, int type, int[] consumed) {
        return helper.dispatchNestedScroll(dxConsumed, dyConsumed, dxUnconsumed, dyUnconsumed,
                offsetInWindow, type, consumed);
    }

    @Override
    public boolean dispatchNestedPreScroll(int dx, int dy, int[] consumed, int[] offsetInWindow, int type) {
        return helper.dispatchNestedPreScroll(dx, dy, consumed, offsetInWindow, type);
    }

    @Override
    public boolean dispatchNestedFling(float velocityX, float velocityY, boolean consumed) {
        return helper.dispatchNestedFling(velocityX, velocityY, consumed);
    }

    @Override
    public boolean dispatchNestedPreFling(float velocityX, float velocityY) {
        return helper.dispatchNestedPreFling(velocityX, velocityY);
    }
  1. 实现ScrollView逻辑,具体含义可以参考该接口的注释。
    // ScrollingView

    @Override
    public ComponentContainer getContainer() {
        return this;
    }

    @Override
    public int getScrollY() {
        return scrollY;
    }

    @Override
    public int getScrollX() {
        return scrollX;
    }

    @Override
    public int getDirection() {
        return getOrientation() + 1;
    }

    @Override
    public void scrollByInternal(int deltaX, int deltaY) {
        // 需要自行计算scrollX、scrollY,因为有时候getScrollValue函数返回有异常
        if (getDirection() == NestedScrollingHelper.SCROLL_AXIS_VERTICAL) {
            scrollY += deltaY;
            if (scrollY < 0) {
                scrollY = 0;
            }
        } else {
            scrollX += deltaX;
            if (scrollX < 0) {
                scrollX = 0;
            }
        }
        scrollTo(scrollX, scrollY);

        if (scrollY > getScrollValue(VERTICAL)) {
            scrollY = getScrollValue(VERTICAL);
        }

        if (scrollX > getScrollValue(HORIZONTAL)) {
            scrollX = getScrollValue(HORIZONTAL);
        }
    }

    @Override
    public boolean disallowInterceptWhenMoving() {
        return true;
    }
Java
1
https://gitee.com/thoseyears/ohos-extension.git
git@gitee.com:thoseyears/ohos-extension.git
thoseyears
ohos-extension
OhosExtension
master

搜索帮助