返回介绍

捋一捋流程

发布于 2024-12-23 22:07:07 字数 5263 浏览 0 评论 0 收藏 0

1、当 NestedScrollingChild(下文用 Child 代替) 要开始滑动的时候会调用 onStartNestedScroll ,然后交给代理类 NestedScrollingChildHelper(下文 ChildHelper 代替)的 onStartNestedScroll 请求给最近的 NestedScrollingParent(下文 Parent 代替).

2、当 ChildHelper 的 onStartNestedScroll 方法 返回 true 表示同意一起处理 Scroll 事件的时候时候,ChildHelper 会通知 Parent 回调 onNestedScrollAccepted 做一些准备动作

3、当 Child 要开始滑动的时候,会先发送 onNestedPreScroll ,交给 ChildHelper 的 onNestedPreScroll 请求给 Parent ,告诉它我现在要滑动多少距离,你觉得行不行,这时候 Parent 根据实际情况告诉 Child 现在只允许你滑动多少距离.然后 ChildHelper 根据 onNestedPreScroll 中回调回来的信息对滑动距离做相对应的调整。

4、在滑动的过程中 Child 会发送 onNestedScroll 通知 ChildeHelpaer 的 onNestedScroll 告知 Parent 当前 Child 的滑动情况。

5、当要进行滑行的时候,会先发送 onNestedFling 请求给 Parent,告诉它 我现在要滑行了,你说行不行,这时候 Parent 会根据情况告诉 Child 你是否可以滑行。

6、Child 通过 onNestedFling 返回的 Boolean 值来觉得是否进行滑行.如果要滑行的话,会在滑行的时候发送 onNestedFling 通知告知 Parent 滑行情况。

7、当滑动事件结束就会 child 发送 onStopNestedScroll 通知 Parent 去做相关操作。

如果你此刻还是看得模模糊糊,没错,是我的责任,啊哈哈哈。要不我给个例子实践下,我们知道 5.0 之前的 ListView 是没有实现 NestedScrollingChild 这个接口的,如果要实现 CoordinatorLayout 里嵌套着 ListView 和 Toolbar,我们上下滑动 ListView 的时候,Toolbar 会随之显现隐藏,就必须重写 ListView.给出我实现的代码吧!

package com.cjj.nestedlistview;

import android.content.Context;
import android.support.v4.view.MotionEventCompat;
import android.support.v4.view.NestedScrollingChild;
import android.support.v4.view.NestedScrollingChildHelper;
import android.support.v4.view.ViewCompat;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.widget.ListView;

public class NestedListView extends ListView implements NestedScrollingChild {

  private NestedScrollingChildHelper mChildHelper;
  private int mLastY;
  private final int[] mScrollOffset = new int[2];
  private final int[] mScrollConsumed = new int[2];
  private int mNestedOffsetY;

  public NestedListView(Context context) {
    super(context);
    init();
  }

  public NestedListView(Context context, AttributeSet attrs) {
    super(context, attrs);
    init();
  }

  public NestedListView(Context context, AttributeSet attrs, int defStyleAttr) {
    super(context, attrs, defStyleAttr);
    init();
  }

  private void init() {
    mChildHelper = new NestedScrollingChildHelper(this);
    setNestedScrollingEnabled(true);
  }


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

  @Override
  public boolean startNestedScroll(int axes) {
    return mChildHelper.startNestedScroll(axes);
  }

  @Override
  public void stopNestedScroll() {
    mChildHelper.stopNestedScroll();
  }

  @Override
  public boolean hasNestedScrollingParent() {
    return mChildHelper.hasNestedScrollingParent();
  }

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

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

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

  @Override
  public boolean dispatchNestedPreFling(float velocityX, float velocityY) {
    return mChildHelper.dispatchNestedPreFling(velocityX, velocityY);
  }


  @Override
  public boolean onTouchEvent(MotionEvent event) {
    final int action = MotionEventCompat.getActionMasked(event);

    int y = (int) event.getY();
    event.offsetLocation(0, mNestedOffsetY);
    switch (action) {
      case MotionEvent.ACTION_DOWN:
        mLastY = y;
        mNestedOffsetY = 0;
        break;
      case MotionEvent.ACTION_MOVE:

        int dy = mLastY - y;
        int oldY = getScrollY();

        startNestedScroll(ViewCompat.SCROLL_AXIS_VERTICAL);
        if (dispatchNestedPreScroll(0, dy, mScrollConsumed, mScrollOffset)) {
          dy -= mScrollConsumed[1];
          event.offsetLocation(0, -mScrollOffset[1]);
          mNestedOffsetY += mScrollOffset[1];
        }
        mLastY = y - mScrollOffset[1];
        if (dy < 0) {
          int newScrollY = Math.max(0, oldY + dy);
          dy -= newScrollY - oldY;
          if (dispatchNestedScroll(0, newScrollY - dy, 0, dy, mScrollOffset)) {
            event.offsetLocation(0, mScrollOffset[1]);
            mNestedOffsetY += mScrollOffset[1];
            mLastY -= mScrollOffset[1];
          }
        }
        stopNestedScroll();
        break;
      case MotionEvent.ACTION_UP:
      case MotionEvent.ACTION_CANCEL:

        stopNestedScroll();

        break;
    }
    return super.onTouchEvent(event);
  }
}

效果:

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文