首页 > 学院 > 开发设计 > 正文

NestedScrolling

2019-11-06 09:58:20
字体:
来源:转载
供稿:网友

NestedScrolling

标签(空格分隔): android


NestedScrolling(ns)是一种嵌套滑动机制,能够互相协同处理事件。

在5.0版本中view已经实现了ns,为了兼容提供了NestedScrollingChild,NestedScrollingParent接口。并且提供了NestedScrollingChildHelper,NestedScrollingParentHelper辅助我们实现ns。 这里写图片描述

NestedScrollingChildHelper源码分析

//开始nestedscrolling(ns)public boolean startNestedScroll(int axes) { //已经启动就直接返回true if (hasNestedScrollingParent()) { // Already in PRogress return true; } //如果是可以嵌套滑动的 if (isNestedScrollingEnabled()) { ViewParent p = mView.getParent(); View child = mView; while (p != null) { //回调onStartNestedScroll和onNestedScrollAccepted if (ViewParentCompat.onStartNestedScroll(p, child, mView, axes)) { mNestedScrollingParent = p; ViewParentCompat.onNestedScrollAccepted(p, child, mView, axes); return true; } //如果没有同意协同处理,则父view设为子view继续向上遍历寻找 if (p instanceof View) { child = (View) p; } p = p.getParent(); } } //到最后都没找到,返回false,没有协同处理者 return false;}//让协同处理的父view先处理,然后返回消费信息给target(ns发起者)public boolean dispatchNestedPreScroll(int dx, int dy, int[] consumed, int[] offsetInWindow) { //判断使能和是否有协同处理者 if (isNestedScrollingEnabled() && mNestedScrollingParent != null) { if (dx != 0 || dy != 0) { int startX = 0; int startY = 0; if (offsetInWindow != null) { //记录开始处于的窗体位置 mView.getLocationInWindow(offsetInWindow); startX = offsetInWindow[0]; startY = offsetInWindow[1]; } //如果没有指定输出,创建临时的 if (consumed == null) { if (mTempNestedScrollConsumed == null) { mTempNestedScrollConsumed = new int[2]; } consumed = mTempNestedScrollConsumed; } consumed[0] = 0; consumed[1] = 0; //回调onNestedPreScroll ViewParentCompat.onNestedPreScroll(mNestedScrollingParent, mView, dx, dy, consumed); //计算窗体位置变化 if (offsetInWindow != null) { mView.getLocationInWindow(offsetInWindow); offsetInWindow[0] -= startX; offsetInWindow[1] -= startY; } return consumed[0] != 0 || consumed[1] != 0; } else if (offsetInWindow != null) { offsetInWindow[0] = 0; offsetInWindow[1] = 0; } } //没有消费 return false;}//target(ns)处理后反馈信息给协同者public boolean dispatchNestedScroll(int dxConsumed, int dyConsumed, int dxUnconsumed, int dyUnconsumed, int[] offsetInWindow) { if (isNestedScrollingEnabled() && mNestedScrollingParent != null) { if (dxConsumed != 0 || dyConsumed != 0 || dxUnconsumed != 0 || dyUnconsumed != 0) { int startX = 0; int startY = 0; if (offsetInWindow != null) { mView.getLocationInWindow(offsetInWindow); startX = offsetInWindow[0]; startY = offsetInWindow[1]; } //回调onNestedScroll ViewParentCompat.onNestedScroll(mNestedScrollingParent, mView, dxConsumed, dyConsumed, dxUnconsumed, dyUnconsumed); if (offsetInWindow != null) { mView.getLocationInWindow(offsetInWindow); offsetInWindow[0] -= startX; offsetInWindow[1] -= startY; } return true; } else if (offsetInWindow != null) { // No motion, no dispatch. Keep offsetInWindow up to date. offsetInWindow[0] = 0; offsetInWindow[1] = 0; } } return false;}//fling处理都很简单,按需回调public boolean dispatchNestedPreFling(float velocityX, float velocityY) { if (isNestedScrollingEnabled() && mNestedScrollingParent != null) { return ViewParentCompat.onNestedPreFling(mNestedScrollingParent, mView, velocityX, velocityY); } return false;}public boolean dispatchNestedFling(float velocityX, float velocityY, boolean consumed) { if (isNestedScrollingEnabled() && mNestedScrollingParent != null) { return ViewParentCompat.onNestedFling(mNestedScrollingParent, mView, velocityX, velocityY, consumed); } return false;}

demo


发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表