CoordinatorLayout + Behavior + NestedScrollView联动原理解析

  1. CoordinatorLayout中重写了generateLayoutParams方法,返回LayoutParams;
@Override
    public LayoutParams generateLayoutParams(AttributeSet attrs) {
        return new LayoutParams(getContext(), attrs);
    }
  1. 而LayoutParams中包含属性Behavior,而Behavior作为中间变量来处理NestedScrollView的滑动与CoordinatorLayout中其他子View的联动;
public static class LayoutParams extends ViewGroup.MarginLayoutParams {
        /**
         * A {@link Behavior} that the child view should obey.
         */
        Behavior mBehavior;
        ...
        LayoutParams(Context context, AttributeSet attrs) {
                ...
                mBehaviorResolved = a.hasValue(
                    R.styleable.CoordinatorLayout_Layout_layout_behavior);
                if (mBehaviorResolved) {
                       mBehavior = parseBehavior(context, attrs, a.getString(
                                   R.styleable.CoordinatorLayout_Layout_layout_behavior));
                 }
                 ...
         }
         ...
}

3.CoordinatorLayout实现了NestedScrollingParent2接口,例如下方法:

    @Override
    public boolean onStartNestedScroll(View child, View target, int axes, int type) {
        boolean handled = false;

        final int childCount = getChildCount();
        for (int i = 0; i < childCount; i++) {
            final View view = getChildAt(i);
            if (view.getVisibility() == View.GONE) {
                // If it's GONE, don't dispatch
                continue;
            }
            final LayoutParams lp = (LayoutParams) view.getLayoutParams();
            final Behavior viewBehavior = lp.getBehavior();
            if (viewBehavior != null) {
                final boolean accepted = viewBehavior.onStartNestedScroll(this, view, child,
                        target, axes, type);
                handled |= accepted;
                lp.setNestedScrollAccepted(type, accepted);
            } else {
                lp.setNestedScrollAccepted(type, false);
            }
        }
        return handled;
    }

    @Override
    public void onNestedScroll(View target, int dxConsumed, int dyConsumed,
            int dxUnconsumed, int dyUnconsumed, int type) {
        final int childCount = getChildCount();
        boolean accepted = false;

        for (int i = 0; i < childCount; i++) {
            final View view = getChildAt(i);
            if (view.getVisibility() == GONE) {
                // If the child is GONE, skip...
                continue;
            }

            final LayoutParams lp = (LayoutParams) view.getLayoutParams();
            if (!lp.isNestedScrollAccepted(type)) {
                continue;
            }

            final Behavior viewBehavior = lp.getBehavior();
            if (viewBehavior != null) {
                viewBehavior.onNestedScroll(this, view, target, dxConsumed, dyConsumed,
                        dxUnconsumed, dyUnconsumed, type);
                accepted = true;
            }
        }

        if (accepted) {
            onChildViewsChanged(EVENT_NESTED_SCROLL);
        }
    }

当调用CoordinatorLayout的onNestedScroll()方法时,就会调用如下代码:

           if (viewBehavior != null) {
                viewBehavior.onNestedScroll(this, view, target, dxConsumed, dyConsumed,
                        dxUnconsumed, dyUnconsumed, type);
                accepted = true;
            }

在以上代码中就会调用behavior中的onNestedScroll,而在使用中我们只要实现behavior中的onNestedScroll中的函数就可以达到联动效果。

发布了13 篇原创文章 · 获赞 2 · 访问量 579

猜你喜欢

转载自blog.csdn.net/qq_42806685/article/details/104375796