android笔记-Android Design支持包控件四(AppBarLayout)

1、简介

       AppBarLayout是一个垂直的LinearLayout,实现了MaterialDesign中app bar的scrolling gestures特性。AppBarLayout的子View应该声明想要具有的“滚动行为”,这可以通过layout_scrollFlags属性或是setScrollFlags()方法来指定。AppBarLayout只有作为CoordinatorLayout的直接子View时才能正常工作,为了让AppBarLayout能够知道何时滚动其子View,我们还应该在CoordinatorLayout布局中提供一个可滚动View,我们称之为scrolling view。scrolling view和AppBarLayout之间的关联,通过将scrolling view的Behavior设为AppBarLayout.ScrollingViewBehavior来建立。

        AppBarLayout主要用来实现这样的功能:当位于同一父容器中的可滚动View发生滚动时,AppBarLayout会根据子View声明的滚动行为来对其子View进行相应的滚动。

        app bar是Material Design中的一个概念,我们可以把它看做是一种ToolBar。我们把TooBar套上一层AppBarLayout,就能把顶部栏玩出各种花样。

2、如何使用

        布局文件定义如下:

<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.study.androidother.DesignSupportLibrary.AppBarlayoutTestActivity">

    <android.support.design.widget.AppBarLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
        <TextView
            android:layout_width="match_parent"
            android:layout_height="200dp"
            android:text="AppBarLayout"
            android:background="@color/colorPrimary"
            android:gravity="center"
            android:textColor="@color/white"
            android:textSize="28sp"
            app:layout_scrollFlags="scroll"/>
    </android.support.design.widget.AppBarLayout>

    <android.support.v4.widget.NestedScrollView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_behavior="@string/appbar_scrolling_view_behavior">
        <TextView
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:gravity="center"
            android:textSize="20sp"
            android:text="NestedScrollView\nNestedScrollView\nNestedScrollView\nNestedScrollView\nNestedScrollView\nNestedScrollView\nNestedScrollView\nNestedScrollView\nNestedScrollView\nNestedScrollView\nNestedScrollView\nNestedScrollView\nNestedScrollView\nNestedScrollView\nNestedScrollView\nNestedScrollView\nNestedScrollView\nNestedScrollView\nNestedScrollView\nNestedScrollView\nNestedScrollView\nNestedScrollView\nNestedScrollView\nNestedScrollView\nNestedScrollView\nNestedScrollView\nNestedScrollView\nNestedScrollView\nNestedScrollView\nNestedScrollView\nNestedScrollView\nNestedScrollView\nNestedScrollView\nNestedScrollView\nNestedScrollView\nNestedScrollView\nNestedScrollView\nNestedScrollView\nNestedScrollView\nNestedScrollView\nNestedScrollView\nNestedScrollView\nNestedScrollView\nNestedScrollView\nNestedScrollView\nNestedScrollView\nNestedScrollView\nNestedScrollView\nNestedScrollView\nNestedScrollView\nNestedScrollView\nNestedScrollView\nNestedScrollView\nNestedScrollView\nNestedScrollView\nNestedScrollView\nNestedScrollView\nNestedScrollView\nNestedScrollView\nNestedScrollView\nNestedScrollView\nNestedScrollView\nNestedScrollView\nNestedScrollView\nNestedScrollView\nNestedScrollView\nNestedScrollView\nNestedScrollView\n"/>
    </android.support.v4.widget.NestedScrollView>

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

注意点:

        1)、AppBarLayout的子view必须指定属性app:layout_scrollFlags

        2)、CoordinatorLayout的子view必须有NestedScrollView或其子类

        3)、NestedScrollView或其子类指定属性app:layout_behavior="@string/appbar_scrolling_view_behavior"

        2、AppBarLayout的layout_scrollFlags

        布局文件如下:

<android.support.design.widget.AppBarLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content">
    <android.support.v7.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="?android:attr/actionBarSize"
        android:background="?attr/colorPrimary"
        app:layout_scrollFlags="scroll" />
</android.support.design.widget.AppBarLayout>

        1)、app:layout_scrollFlags="scroll"

        2)、enterAlways。值设为enterAlways的View, 当ScrollView往下滚动时,该View会直接往下滚动。而不用考虑ScrollView是否在滚动。

            app:layout_scrollFlags="scroll|enterAlways"

        3)、exitUntilCollapsed。值设为exitUntilCollapsed的View,当这个View要往上逐渐“消逝”时,会一直往上滑动,直到剩下的的高度达到它的最小高度后,再响应ScrollView的内部滑动事件。

        app:layout_scrollFlags="scroll|exitUntilCollapsed"

        4)、enterAlwaysCollapsed:是enterAlways的附加选项,一般跟enterAlways一起使用,它是指,View在往下“出现”的时候,首先是enterAlways效果,当View的高度达到最小高度时,View就暂时不去往下滚动,直到ScrollView滑动到顶部不再滑动时,View再继续往下滑动,直到滑到View的顶部结束。

        app:layout_scrollFlags="scroll|enerAlways|enterAlwaysCollapsed"

3、设置监听

        监听AppBarLayout移动了多少距离

        appBarLayout = (AppBarLayout) findViewById(R.id.app_bar_layout);
        appBarLayout.addOnOffsetChangedListener(new AppBarLayout.OnOffsetChangedListener() {
            @Override
            public void onOffsetChanged(AppBarLayout appBarLayout, int verticalOffset) {
                Log.i(TAG, "----onOffsetChanged--verticalOffset:" + verticalOffset + ",ScrollRange:" + appBarLayout.getTotalScrollRange());
            }
        });

        appBarLayout.getTotalScrollRange()获取AppBarLayout可以移动的范围

4、注意

        1)、AppBarLayout的滑动是通过AppBarLayout.Behavior实现。虽然布局文件没有指定AppBarLayout的Behavior,但是AppBarLayout的默认Behavior是AppBarLayout.Behavior。CoordinatorLayout的onTouchEvent()调用了AppBarLayout.Behavior的onTouchEvent()。

        2)、在CoordinatorLayout中AppBarLayout作为dependency,NestedScrollView作为child。

5、AppBarLayout为什么可以滑动

下面是CoordinatorLayout的onTouchEvent方法:

    public boolean onTouchEvent(MotionEvent ev) {
        boolean handled = false;

        final int action = ev.getActionMasked();

        if (mBehaviorTouchView != null || (cancelSuper = performIntercept(ev, TYPE_ON_TOUCH))) {
            // Safe since performIntercept guarantees that
            // mBehaviorTouchView != null if it returns true
            final LayoutParams lp = (LayoutParams) mBehaviorTouchView.getLayoutParams();
            final Behavior b = lp.getBehavior();
            if (b != null) {
                handled = b.onTouchEvent(this, mBehaviorTouchView, ev);
            }
        }
    }

performIntercept中会调用AppBarLayout的Behavior的onTouchEvent,Behavior的onTouchEvent返回true时就会给mBehaviorTouchView赋值为AppBarLayout。所以上面代码中就会把CoordinatorLayout的onTouchEvent交给AppBarLayout的onTouchEvent处理。因此就可以实现AppBarLayout的滑动。

当AppBarLayout的滑动后由于CoordinatorLayout的作用就会调用NestedScrollView设置的app:layout_behavior="@string/appbar_scrolling_view_behavior"让NestedScrollView也跟着AppBarLayout一起滑动。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值