6AppBarLayout与scrollFlags

6AppBarLayout与scrollFlags

AppBarLayout分组

这里说过AppBarLayout可以分为可滑出和不可滑出上下2部分,其实细致一点可以分三部分,如下图所示,下滑最后出现(part 1),下滑立刻出现(part2),无法滑出(part3),其中part1和2合起来就是可以滑出的部分。

xml代码如下

   <android.support.design.widget.AppBarLayout
        android:layout_width="match_parent"
        android:theme="@style/AppTheme.AppBarOverlay"
        android:layout_height="wrap_content">


        <TextView
            android:gravity="center"
            app:layout_scrollFlags="scroll"
            android:textSize="20sp"
            android:text="下滑最后出现"
            android:background="#447700"
            android:layout_width="match_parent"
            android:layout_height="70dp" />


        <TextView
            android:gravity="center"
            app:layout_scrollFlags="scroll|enterAlways"
            android:textSize="20sp"
            android:text="下滑立刻出现"
            android:background="#004477"
            android:layout_width="match_parent"
            android:layout_height="100dp" />


        <TextView
            android:gravity="center"
            android:textSize="20sp"
            android:text="无法滑出去"
            android:background="#ff0000"
            android:layout_width="match_parent"
            android:layout_height="100dp" />

    </android.support.design.widget.AppBarLayout>

主要关注layout_scrollFlags,可以看到part3无scroll标志,代表无法滚出;part2是scroll|enterAlways代表下滑立刻出现;part1是scroll下滑的时候最后出现。
为什么会这样,主要和mDownPreScrollRange、mDownScrollRange有关,可以看下边代码。mDownPreScrollRange控制着嵌套滑动的父view的onNestedPreScroll部分可滑距离,mDownScrollRange控制着嵌套滑动的父view的onNestedScroll部分。

//AppBarLayout
    /**
     * Return the scroll range when scrolling down from a nested pre-scroll.
     */
    private int getDownNestedPreScrollRange() {
        if (mDownPreScrollRange != INVALID_SCROLL_RANGE) {
            // If we already have a valid value, return it
            return mDownPreScrollRange;
        }

        int range = 0;
        for (int i = getChildCount() - 1; i >= 0; i--) {
            final View child = getChildAt(i);
            final LayoutParams lp = (LayoutParams) child.getLayoutParams();
            final int childHeight = child.getMeasuredHeight();
            final int flags = lp.mScrollFlags;

            if ((flags & LayoutParams.FLAG_QUICK_RETURN) == LayoutParams.FLAG_QUICK_RETURN) {
                // First take the margin into account
                range += lp.topMargin + lp.bottomMargin;
                // The view has the quick return flag combination...
                if ((flags & LayoutParams.SCROLL_FLAG_ENTER_ALWAYS_COLLAPSED) != 0) {
                    // If they're set to enter collapsed, use the minimum height
                    range += ViewCompat.getMinimumHeight(child);
                } else if ((flags & LayoutParams.SCROLL_FLAG_EXIT_UNTIL_COLLAPSED) != 0) {
                    // Only enter by the amount of the collapsed height
                    range += childHeight - ViewCompat.getMinimumHeight(child);
                } else {
                    // Else use the full height
                    range += childHeight;
                }
            } else if (range > 0) {
                // If we've hit an non-quick return scrollable view, and we've already hit a
                // quick return view, return now
                break;
            }
        }
        return mDownPreScrollRange = Math.max(0, range - getTopInset());
    }

    /**
     * Return the scroll range when scrolling down from a nested scroll.
     */
    private int getDownNestedScrollRange() {
        if (mDownScrollRange != INVALID_SCROLL_RANGE) {
            // If we already have a valid value, return it
            return mDownScrollRange;
        }

        int range = 0;
        for (int i = 0, z = getChildCount(); i < z; i++) {
            final View child = getChildAt(i);
            final LayoutParams lp = (LayoutParams) child.getLayoutParams();
            int childHeight = child.getMeasuredHeight();
            childHeight += lp.topMargin + lp.bottomMargin;

            final int flags = lp.mScrollFlags;

            if ((flags & LayoutParams.SCROLL_FLAG_SCROLL) != 0) {
                // We're set to scroll so add the child's height
                range += childHeight;

                if ((flags & LayoutParams.SCROLL_FLAG_EXIT_UNTIL_COLLAPSED) != 0) {
                    // For a collapsing exit scroll, we to take the collapsed height into account.
                    // We also break the range straight away since later views can't scroll
                    // beneath us
                    range -= ViewCompat.getMinimumHeight(child) + getTopInset();
                    break;
                }
            } else {
                // As soon as a view doesn't have the scroll flag, we end the range calculation.
                // This is because views below can not scroll under a fixed view.
                break;
            }
        }
        return mDownScrollRange = Math.max(0, range);
    }

实际效果如下所示

scrollFlags

-scroll代表可滚动,被标注后算到mTotalScrollRange里,要写其他flag必须先写scroll才有效
-enterAlways下滑,这个view立刻跑出来,算在mDownPreScrollRange内
-enterAlwaysCollapsed下滑的时候在onNestedPreScroll阶段先滑出一个最小高度,这个参数我试了下都存在一定问题,没找到一个合适的场景。用enterAlwaysCollapsed必须先写 scroll和enterAlways
-exitUntilCollapsed 向上滚动直到折叠,往往用于CollapsingToolbarLayout内,后边会有介绍

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值