214

玩转AppBarLayout,更酷炫的顶部栏 - 简书

 6 years ago
source link: http://www.jianshu.com/p/d159f0176576
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

我的CSDN博客同步发布:玩转AppBarLayout,更酷炫的顶部栏

上一篇文章[《CoordinateLayout的使用如此简单 》]上一篇文章《CoordinateLayout的使用如此简单 》CoordinateLayout的使用做了讲解,今天我们再讲解常常与其一起使用的几个ViewAppBarLayoutCollapsingToolbarLayout以及Toolbar。一下子出现3个陌生的View,是不是觉得很慌张~,很多人都写了这几个布局的使用,但是他们却没有有针对性的单独讲解每个View的作用以及如何使用,我看的很多文章都是一上来就把AppBarLayoutCollapsingToolbarLayout以及Toolbar写到一个布局里面去,然后一个一个布局属性去说,一下子感觉好混乱,本文是从Toolbar开始说起,最终让你把这3个View彻底掌握下来!

其实,这三个View都是针对我们以往常用的ActionBar的,就是针对我们的App的顶部的Bar玩各种花样~我们往下看,看看他们把我们的App的"顶部栏"玩出个什么花样!

1 Toolbar

Toobar主要是用来替换ActionBar的,换句话说,ActionBar能做的,Toolbar都能做。如果你对ActionBar的使用比较熟悉,你会发现Toolbar使用起来非常简单。ok,既然是替换,当然用Toolbar的时候就得先去把ActionBar给隐藏掉啦~

隐藏ActionBar的方法有很多,可以通过代码的方式隐藏,也可以通过配置文件的方式,我们主要是通过配置文件的方式来隐藏。在我们的styles.xml文件中的AppTheme标签中加入如下两行:

<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>

当然了,你也可以新建一个<style>标签,将上面两行代码加入,并且将这个新建的标签作为<application>theme。还可以选择通过将AppTheme的parent设置为Theme.AppCompat.Light.NoActionBar的方式。方法很多,可以自己随便选。

接下来就是将Toolbar放入到布局文件(没啥好解释的):

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

最后将Toobar作为“ActionBar”来用

 Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        toolbar.setTitle("这里是Title");
        toolbar.setSubtitle("这里是子标题");
        toolbar.setLogo(R.drawable.icon); 
        setSupportActionBar(toolbar);

可以对Toolbar设置Logo、标题、子标题等等还有很多其他的设置,自己去慢慢玩,这里不提啦。当然了,也可以在布局文件中设置这些,在布局文件设置就不写啦,hongyang大神有篇博客写的挺好的《 Android 5.x Theme 与 ToolBar 实战 》可以去参考一下。

看看效果:

Toolbar

如果Toolbar仅仅是用来对以往的ActionBar做一次替换,那也太没创意啦!完全没必要去替换了,因为它们表现出来的都是一样的,而且并没有让我们觉得用起来比ActionBar方便。那为啥要替换呢,总应该有他的理由吧:ActionBar是固定在顶部,并不能移动,我觉得这是最大的不好,而我们的ToolBar可以让我们随便摆放,就就可以带来很多灵活性和效果啦!

正如你所看的这样,Toolbar根本就不够看的,一点都不复杂。接下来我们继续学习在Toolbar上面再套一层父View,让Toolbar更有互动性。

2 AppBarLayout

AppBarLayout继承自LinearLayout,布局方向为垂直方向。所以你可以把它当成垂直布局的LinearLayout来使用。AppBarLayout是在LinearLayou上加了一些材料设计的概念,它可以让你定制当某个可滚动View的滚动手势发生变化时,其内部的子View实现何种动作。

请注意:上面提到的某个可滚动View,可以理解为某个ScrollView。怎么理解上面的话呢?就是说,当某个ScrollView发生滚动时,你可以定制你的“顶部栏”应该执行哪些动作(如跟着一起滚动、保持不动等等)。那某个可移动的View到底是哪个可移动的View呢?这是由你自己指定的!如何指定,我们后面说。

2.1 AppBarLayout子View的动作

内部的子View通过在布局中加app:layout_scrollFlags设置执行的动作,那么app:layout_scrollFlags可以设置哪些动作呢?分别如下:

(1) scroll:值设为scroll的View会跟随滚动事件一起发生移动。

什么意思呢?简单的说,就是当指定的ScrollView发生滚动时,该View也跟随一起滚动,就好像这个View也是属于这个ScrollView一样。

一张gif足以说明:

scroll

对应的布局文件

<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>

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

看个动画片(Y(o)Y)(ToolBar高度设为:?android:attr/actionBarSize,app:layout_scrollFlags="scroll|enterAlways"):

scroll|enterAlways

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

怎么理解呢?简单解释:在ScrollView往上滑动时,首先是View把滑动事件“夺走”,由View去执行滑动,直到滑动最小高度后,把这个滑动事件“还”回去,让ScrollView内部去上滑。看个gif感受一下(图中将高度设的比较大:200dp,并将最小高度设置为?android:attr/actionBarSize,app:layout_scrollFlags="scroll|exitUntilCollapsed"):

scroll|exitUntilCollapsed

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

来个gif感受一下(图中将高度设的比较大:200dp,并将最小高度设置为?android:attr/actionBarSize,app:layout_scrollFlags="scroll|enerAlways|enterAlwaysCollapsed"):

scroll|enerAlways|enterAlwaysCollapsed

2.2 将AppBarLayout与ScrollView关联起来

前面说了一直反复说“当ScrollView发生滚动时”,那么怎么将AppBarLayout与ScrollView关联起来呢?我们注意到,AppBarLayout与ScrollView之间动作“相互依赖”,这不就是我们上一篇《CoordinateLayout的使用如此简单 》所学的内容吗?把ScrollView和AppBarLayout作为CoordinateLayout的子View,然后编写一个Behavior,在这个Behavior里面判断当前的操作是应该让ScrollView时刻保持在AppBarLayout之下(即只要改变AppBarLayout的位置就可以一起滑动),还是应该让ScrollView内部滚动而不让AppBarLayout位置发生变化等等这些需求,都是可以在Behavior里面处理的。你可以去针对你的ScrollView编写Behavior。然而,我们看到我们的AppBarLayout事先的功能比较复杂,如果我们自己去定义这样的效果,代码非常复杂,还要考虑很多方面,好在Android帮我们写好啦,我们直接用就是了,这个ScrollView就是NestedScrollView,请注意,它并没有继承ScrollView,它继承的是FrameLayout,但是它实现的效果把它可以看成是ScrollView。

把NestedScrollView放入到我们的layout文件里面就可以啦~~,很方便

 <android.support.v4.widget.NestedScrollView

        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:layout_behavior="@string/appbar_scrolling_view_behavior">

       <!--将你的内容放在这里-->

    </android.support.v4.widget.NestedScrollView>

有没有注意到有个属性:app:layout_behavior="@string/appbar_scrolling_view_behavior",它就是指定Behavior的,appbar_scrolling_view_behavior对应的类的名称是:android.support.design.widget.AppBarLayout$ScrollingViewBehavior感兴趣的可以去分析源码。

好了,我们现在会用AppBarLayout啦~是不是发现用起来so easy!接下来我们把剩下CollapsingToolbarLayout的给"消化"掉!

3 CollapsingToolbarLayout

CollapsingToolbarLayout是用来对Toolbar进行再次包装的ViewGroup,主要是用于实现折叠(其实就是看起来像伸缩~)的App Bar效果。它需要放在AppBarLayout布局里面,并且作为AppBarLayout的直接子ViewCollapsingToolbarLayout主要包括几个功能(参照了官方网站上内容,略加自己的理解进行解释):

(1) 折叠Title(Collapsing title):当布局内容全部显示出来时,title是最大的,但是随着View逐步移出屏幕顶部,title变得越来越小。你可以通过调用setTitle函数来设置title。

(2)内容纱布(Content scrim):根据滚动的位置是否到达一个阀值,来决定是否对View“盖上纱布”。可以通过setContentScrim(Drawable)来设置纱布的图片.

(3)状态栏纱布(Status bar scrim):根据滚动位置是否到达一个阀值决定是否对状态栏“盖上纱布”,你可以通过setStatusBarScrim(Drawable)来设置纱布图片,但是只能在LOLLIPOP设备上面有作用。

(4)视差滚动子View(Parallax scrolling children):子View可以选择在当前的布局当时是否以“视差”的方式来跟随滚动。(PS:其实就是让这个View的滚动的速度比其他正常滚动的View速度稍微慢一点)。将布局参数app:layout_collapseMode设为parallax

(5)将子View位置固定(Pinned position children):子View可以选择是否在全局空间上固定位置,这对于Toolbar来说非常有用,因为当布局在移动时,可以将Toolbar固定位置而不受移动的影响。 将app:layout_collapseMode设为pin

了解这些概念后,我们来看看布局吧~

<?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"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >


    <android.support.design.widget.AppBarLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">

        <android.support.design.widget.CollapsingToolbarLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            app:expandedTitleMarginEnd="64dp"
            app:expandedTitleMarginStart="48dp"
            app:layout_scrollFlags="scroll|exitUntilCollapsed">

            <ImageView
                android:id="@+id/main.backdrop"
                android:layout_width="wrap_content"
                android:layout_height="300dp"
                android:scaleType="centerCrop"
                android:src="@drawable/material_img"
                app:layout_collapseMode="parallax" />

            <android.support.v7.widget.Toolbar
                android:id="@+id/toolbar"
                android:layout_width="match_parent"
                android:layout_height="?android:attr/actionBarSize"
                app:layout_collapseMode="pin"  />

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

    <android.support.v4.widget.NestedScrollView

        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:paddingTop="50dp"
        app:layout_behavior="@string/appbar_scrolling_view_behavior">

        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="@string/my_txt"
            android:textSize="20sp" />

    </android.support.v4.widget.NestedScrollView>

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



上面的都看得懂吧,每个陌生的属性都是讲过的哦,忘记了的话回头看,稍微解释一下,图片被设置为有视差的滑动,Toolbar设置为固定不动,另外,CollapsingToolbarLayout会对title进行放大和缩小,我们看看效果吧~

CollapsingToolbarLayout效果

如果你希望拖动过程中状态栏是透明的,可以在CollapsingToolbarLayout中加 app:statusBarScrim="@android:color/transparent",并且在onCreate中调用getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS)将状态栏设置为透明就好啦~

献上源码,请笑纳:http://download.csdn.net/detail/huachao1001/9538934


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK