CoordinatorLayout、AppBarLayout、 Toolbar、CollapsingToolbarLayout、NestedScrollView 综合使用,详细解析

来源:互联网 发布:怎样看跌停龙虎榜数据 编辑:程序博客网 时间:2024/05/22 06:25

这篇文章主要介绍CoordinatorLayout、AppBarLayout、 Toolbar、CollapsingToolbarLayout、NestedScrollView的使用。看上去很多,其实真的很简单。

我们先来看一下,使用这些控件最终实现的效果图,然后根据源码,逐一分析他所使用到的控件,及每个控件配置的属性.

这里写图片描述

完整代码下载地址。

这里给出代码,主要体现这些控件的嵌套关系,让你有总体的认识。

<android.support.design.widget.CoordinatorLayout...此处省略若干代码>           <android.support.design.widget.AppBarLayout             ...此处省略若干代码 >              <android.support.design.widget.CollapsingToolbarLayout                ...此处省略若干代码>                <ImageView                    android:layout_width="match_parent"                    android:layout_height="match_parent"                    android:fitsSystemWindows="true"                    android:scaleType="centerCrop"                    android:src="@mipmap/ic_1"                    app:layout_collapseMode="parallax"                    app:layout_collapseParallaxMultiplier="0.5"/>                <android.support.v7.widget.Toolbar                    android:id="@+id/toolbar"                    android:layout_width="match_parent"                    android:layout_height="56dp"                    app:layout_collapseMode="pin"                    android:elevation="4dp"                    />            </android.support.design.widget.CollapsingToolbarLayout>        </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"            >           ...此处省略若干代码        </android.support.v4.widget.NestedScrollView>    </android.support.design.widget.CoordinatorLayout>

1、CoordinatorLayout

这个控件到底能做什么呢?从字面上意思是协调子View的,就是我们滑动(或其他操作)一个Layout,另一个Layout自动执行相应已经设定好的操作。看下图就明白了

这里写图片描述

蓝色的是一个自定义View,可跟随手指移动

黄色的是一个Button。

他们之间的运动关系:它们在竖直方向同步移动,在水平方向相反。

这个效果如果让你不用CoordinatorLayout去实现,应该没有任何问题,但是代码的耦合度应该非常大,你的代码必须要持有2个View的引用,然后在onTouchEvent里面做各种判断。如果我们想要实现的功能是,有更多的View要根据蓝色的View的移动相应作出响应,那么那就得在蓝色View的onTounchEvent里面针对其他的View处理各种逻辑。这耦合度未免太伤感了~

而CoordinatorLayout既然号称能帮我们协调子View的布局,我们接下来看看CoordinatorLayout如何实现~

CoordinatorLayout使用

在使用前,需要了解三个概念:

  • Dependency View (上图中的蓝色view)Child依赖的View
  • child View (上图中的黄色Button)CoordinatorLayout的子View,操作Dependency View 时,根据Behavior类,对child View自动执行相关操作
  • Behavior类,指定Child View的运动规则。自定义Behavior类,需要实现两个方法

简而言之,就是Dependency View发生了变化,那么Child View就要相应发生变化。
发生变化是具体发生什么变化呢?这里就要引入Behavior,Child发生变化的代码都是放在Behavior类里面。

怎么使用Behavior呢,首先,我们定义一个类,继承CoordinatorLayout.Behavior < T>,其中,泛型参数T是我们要执行动作的View类,也就是Child。然后就是去实现Behavior的两个方法:

/*** 判断child的布局是否依赖dependency*/   @Override public boolean layoutDependsOn(CoordinatorLayout parent, T child, View dependency) {    boolean rs;    //根据逻辑判断rs的取值    //返回false表示child不依赖dependency,ture表示依赖    return rs;  }/*** 当dependency发生改变时(位置、宽高等),执行这个函数* 返回true表示child的位置或者是宽高要发生改变,否则就返回false*/@Overridepublic boolean onDependentViewChanged(CoordinatorLayout parent, T child, View dependency) {     //child要执行的具体动作        return true;}

看一下这个示例中的Behavior是怎么实现的

public class MyBehavior extends CoordinatorLayout.Behavior<Button> {    private int width;    public MyBehavior(Context context, AttributeSet attrs) {        super(context, attrs);        DisplayMetrics display = context.getResources().getDisplayMetrics();        width = display.widthPixels;    }    @Override    public boolean layoutDependsOn(CoordinatorLayout parent, Button child, View dependency) {        //如果dependency是TempView的实例,说明它就是我们所需要的Dependency        return dependency instanceof TempView;    }    //每次dependency位置发生变化,都会执行onDependentViewChanged方法    @Override    public boolean onDependentViewChanged(CoordinatorLayout parent, Button btn, View dependency) {        //根据dependency的位置,设置Button的位置        int top = dependency.getTop();        int left = dependency.getLeft();        int x = width - left - btn.getWidth();        int y = top;        setPosition(btn, x, y);        return true;    }    private void setPosition(View v, int x, int y) {        CoordinatorLayout.MarginLayoutParams layoutParams = (CoordinatorLayout.MarginLayoutParams) v.getLayoutParams();        layoutParams.leftMargin = x;        layoutParams.topMargin = y;        v.setLayoutParams(layoutParams);    }}

OK,现在我们定义好了跟随Dependency一直变化的动作(Behavior),接下来我们就要指定哪个View来执行这些操作。方法很简单,直接在布局文件指定就好:

<?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">    <Button        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:background="@color/colorPrimary"        app:layout_behavior="cn.xuexuan.newui.CoordinatorBehavior"/>    <cn.xuexuan.newui.MoveView        android:layout_width="50dp"        android:layout_height="50dp"        android:background="@color/colorAccent"        /></android.support.design.widget.CoordinatorLayout>

至此,就可以实现上面动图的效果。

在最开始的那幅图中,在滑动时,自动改变AppBarLayout。你可能会想到,如果要实现图一的效果,那这个Behavior,肯定很难写啊。但是不用担心,android已经提供了这样的Behavior。来看一下面的这个控件

2、AppBarLayout

AppBarLayout 是继承LinerLayout实现的一个ViewGroup容器组件,它是为了Material Design设计的AppBar,支持手势滑动操作。默认的AppBarLayout是垂直方向的,它的作用是把AppBarLayout包裹的内容都作为AppBar。

它可以让你定制,当指定的View滚动时,AppBarLayout内部的子View实现何种动作。你想到了CoordinatorLayout,没错,并且AppBarLayout定义好了Behavior,只需要加上下面这句代码就可以使用。

app:layout_behavior="@string/appbar_scrolling_view_behavior"

AppBarLayout,相当于CoordinatorLayout的dependency View。上行代码需要加到CoordinatorLayout的child view中(下面会介绍)。

AppBarLayout子View的动作

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

1、 scroll: 跟随滚动事件一起发生移动。

就是当指定的ScrollView发生滚动时,该View也跟随一起滚动,就好像这个View也是属于这个ScrollView一样。想滚动就必须设置这个。可配合下面几项一起使用
这里写图片描述

2、 enterAlways: 当ScrollView滑动时,先滑动AppBarLayout,再响应ScrollView的内部滑动事件

这里写图片描述

3、 enterAlwaysCollapsed:是enterAlways的附加选项,一般跟enterAlways一起使用。往下滑动时,当AppBarLayout的高度达到最小高度时,就暂时不去往下滚动,直到ScrollView滑动到顶部不再滑动时,AppBarLayout再继续往下滑动

这里写图片描述

4、 exitUntilCollapsed:当AppBarLayout要往上逐渐“消逝”时,会一直往上滑动,直到剩下的的高度达到它的最小高度后,再响应ScrollView的内部滑动事件。

这里写图片描述

3、NestedScrollView

图一中,滚动操作,AppBarLayout会进行收缩和扩张,这个可滚动的view,就是这个控件。

它并没有继承ScrollView,它继承的是FrameLayout,但是它实现的效果把它可以看成是ScrollView。

作为CoordinatorLayout的child view,并在xml设置AppBarLayout类已经实现的Behavior。

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

@string/appbar_scrolling_view_behavio 是AppBarLayout中的Behavior类名

你可能会想到,既然Behavior已经在AppBarLayout类中实现了,干嘛还非要使用NestedScrollView,使用ScrollView不可以吗?

经过我的测试,换做ScrollView还真的不行,但是看到这篇文章中,用在了SwipeRefreshLayout、ViewPager、RecycleView上,我猜想,难道只能用在android.support.v4.widget包里的控件上???

讲到这里你可能已经大概有个了解,但是好像还是有点不明白,AppBarLayout中的图片,滑动效果怎么实现,返回箭头怎么固定住的呢,title颜色渐变怎么控制?那就让我们来看看下面这个控件,一切都会明白

4、CollapsingToolbarLayout

CollapsingToolbarLayout作用是提供了一个可以折叠的Toolbar,它继承FrameLayout,它可以控制包含在CollapsingToolbarLayout中的控件(如:ImageView、Toolbar)在响应layout_behavior事件时作出相应的scrollFlags滚动事件(移除屏幕或固定在屏幕顶端)。

它通常作为AppBarLayout子View使用,所以可以给它设置layout_scrollFlags。

在CollapsingToolbarLayout的子View中可以设置以下属性:

  • layout_collapseMode (折叠模式) - 有两个值:

    • pin - 设置为这个模式时,当CollapsingToolbarLayout完全收缩后,Toolbar还可以保留在屏幕上。
    • parallax - 设置为这个模式时,在内容滚动时,CollapsingToolbarLayout中的View(比如ImageView)也可以同时滚动,实现视差滚动效果,和layout_collapseParallaxMultiplier搭配使用。
    • layout_collapseParallaxMultiplier(视差因子) - 设置视差滚动因子,值为:0~1。
  • contentScrim - 设置当CollapsingToolbarLayout完全折叠(收缩)后的背景颜色

  • expandedTitleMarginStart - 设置扩张时候(还没有收缩时)title向左填充的距离。

改变title的字体颜色:

扩张时候的title颜色:

mCollapsingToolbarLayout.setExpandedTitleColor();

收缩后在Toolbar上显示时的title的颜色:

mCollapsingToolbarLayout.setCollapsedTitleTextColor();

更多详细用法:AndroidASD完全解析06之CollapsingToolbarLayout

5、Toolbar

Android 3.0 Android 推了 ActionBar 这个控件,而到了2013 年 Google 开始大力地推动所谓的 android style,想要逐渐改善过去 android 纷乱的界面设计,希望让终端使用者尽可能在 android 手机有个一致的操作体验。官方在某些程度上认为 ActionBar 限制了 android app 的开发与设计的弹性,在Lollipop推出了ToolBar来取代过去 actionbar 的控件,而现在于 material design 中也对之有一个统一名称:app bar,在未来的 android app 中,就以 toolbar 这个元件来实现。

由于ToolBar是API 21才有的UI控件,为了适配低版本的系统,在AppCompat V7当中也提供了ToolBar,所以我们一般在开发的时候使用的是V7中的ToolBar

介绍一下使用Toolbar的步骤:

1、style

你对ActionBar的使用比较熟悉,你会发现Toolbar使用起来非常简单。ok,既然是替换,当然用Toolbar的时候就得先去把ActionBar给隐藏掉啦~

<!-- Base application theme. --> <style name="AppTheme.Base" parent="Theme.AppCompat">   <!-- Customize your theme here. -->   <item name="windowActionBar">false</item>   <item name="android:windowNoTitle">true</item> </style> <style name="AppTheme" parent="AppTheme.Base"></style>

2、xml文件

在 activity_main.xml 里面添加 Toolbar 控件:

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

请记得用 support v7 里的 toolbar,不然然只有 API Level 21 也就是 Android 5.0 以上的版本才能使用。

3 、程序 (Java)

在 java文件 中加入 Toolbar 的声明:

Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);setSupportActionBar(toolbar);

那为啥要用ToolBar替换ActionBar呢,总应该有他的理由吧:ActionBar是固定在顶部,并不能移动,我觉得这是最大的不好,而ToolBar可以随便摆放,就可以带来很多灵活性和效果啦!

因为在这个项目中使用ToolBar特性不多,这里不过多介绍,想了解更多可以参考android:ToolBar详解(手把手教程)

参考:

CoordinatorLayout的使用如此简单

玩转AppBarLayout,更酷炫的顶部栏

关于 APP Bar(ToolBar、CoordinatorLayout、AppBarLayout、CollapsingToolbarLayout)

Material Design之CollapsingToolbarLayout使用

android:ToolBar详解(手把手教程)

Material Design系列之ToolBar即将取代ActionBar

1 0
原创粉丝点击