Android Design Support Library全解:Part 5 CoordinatorLayout 与其他控件的联动

简介: Android Design Support Library系列第5弹,TabLayout 实现滑动选项卡1504424076347.png在前文Part 4 – TabLayout中我们已经使用CoordinatorLayout和其他控件配合过(比如Snackbar出现时,FAB上移),这里来重点介绍其使用方法。

Android Design Support Library系列第5弹,TabLayout 实现滑动选项卡

1504424076347.png

在前文Part 4 – TabLayout中我们已经使用CoordinatorLayout和其他控件配合过(比如Snackbar出现时,FAB上移),这里来重点介绍其使用方法。CoordinatorLayout是Android Design Support Library中最为重要的控件了,它的作用是用来组织不同子View之间的协作和联动。请注意,CoordinatorLayout的布局类似于FrameLayout,子控件会默认以左上角为基准重叠。

1. Toolbar的layout_scrollFlags属性

在上一篇文章Part 4 – TabLayout介绍TabLayout的布局时,有的读者就发现了,Toolbar定义了layout_scrollFlags属性,该属性其实就是在设定滚动事件。下面举例说明:

<?xml version="1.0" encoding="utf-8"?>
<!--发起和响应滚动事件的控件,必须以CoordinatorView为父控件,否者滚动事件无法响应-->
<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.android.srx.github.designsupportlibrarydemo.TabLayoutActivity">

    <!--AppBarLayout 顶部栏布局 其本质是垂直方向的LinearLayout-->
    <android.support.design.widget.AppBarLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
        <!--ToolBar和TabLayout作为顶部栏的一部分,ToolBar注意其layout_scrollFlags属性-->
        <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            app:layout_scrollFlags="scroll|enterAlways"
            android:popupTheme="@style/ThemeOverlay.AppCompat.ActionBar"/>
        <android.support.design.widget.TabLayout
            android:id="@+id/tabs"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            app:tabMode="scrollable"
            app:tabIndicatorColor="@color/colorAccent"
            android:scrollbarSize="30dp"/>
    </android.support.design.widget.AppBarLayout>



    <!--滚动事件的发起者-->
    <android.support.v4.view.ViewPager
        android:id="@+id/viewpager"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_marginTop="60dp"/>


    <!--FAB需要依赖CoordinatorLayout响应Snackbar浮现时的位移效果-->
    <android.support.design.widget.FloatingActionButton
        android:id="@+id/btnFloatingAction"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom|right|end"
        android:src="@drawable/ic_plus"
        android:visibility="gone"
        app:fabSize="normal"
        app:borderWidth="2dp"
        app:rippleColor="@color/colorPrimaryDark"
        app:elevation="12dp"
        android:layout_marginBottom="@dimen/activity_vertical_margin"
        android:layout_marginEnd="@dimen/activity_horizontal_margin"/>

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

后台代码并没有特殊处理同上篇文章一样,其运行效果就不同了:


Toolbar&CoordinatorLayout.gif

当向下滚动屏幕时,Toolbar会伴随着滚动事件而消失;反之,当向上滚动屏幕时,Toolbar又会随之出现。这样的效果正式因为其定义了属性app:layout_scrollFlags.

app:layout_scrollFlags="scroll|......"

  • scroll:所有想滚动出屏幕的view都必修要设置这个flag,没有设置这个flag的view将被固定在屏幕顶部。例如,TabLayout没有设置这个值,将会停留在屏幕顶部。
  • enterAlways:设置这个flag时,向下的滚动都会导致该view变为可见,启用快速“返回模式”。
  • enterAlwaysCollapsed:当你的视图已经设置minHeight属性又使用此标志时,你的视图只能已最小高度进入,只有当滚动视图到达顶部时才扩大到完整高度。
  • exitUntilCollapsed: 滚动退出屏幕,最后折叠在顶端。

当Toolbar定义app:layout_scrollFlags属性之后,如果同在CoordinatorLayout下的其他控件(比如ViewPagerListView,默认包含,无需声明)发出滚动事件:
app:layout_behavior="@string/appbar_scrolling_view_behavior
时,Toolbar就可以响应滚动事件而消失或出现了。
如果CoordinatorLayout包含的子视图没有默认带有滚动属性,就需要手动设置app:layout_behavior属性。

为了使得Toolbar有滑动效果,必须做到如下三点

  1. CoordinatorLayout作为布局的父布局容器;
  2. 给需要滑动的组件设置app:layout_scrollFlags=”scroll|......”属性;
  3. 给滑动的组件设置app:layout_behavior属性。

另外,关于FloatActionButton在Snackbar出现时自动向上移动,这是由于FloatActionButton会有一个默认的Behavior来检测Snackbar的出现,所以一不用特意生命。当然用户可以自定义Behavior来实现更为复杂的效果,我们稍后再谈。

2. CollapsingToolbarLayout:

为了实现Toolbar的折叠效果,我们要介绍一位新朋友——CollapsingToolbarLayout。该布局继承自FrameLayout,其子视图的布局与LinearLayout垂直方向排放类似。

CollapsingToolbarLayout中设有app:layout_scrollFlags属性,可以控制其子控件响应滚动事件。除此之外,其好包括如下属性:

  • app:contentScrim:收缩后的颜色背景;

  • app:title: ToolBar的标题,当CollapsingToolbarLayout全屏没有折叠时,title显示的是大字体,在折叠的过程中,title不断变小到一定大小的效果。我们可以通过代码调用setTitle(CharSequence)方法设置title。

  • app:layout_collapseParallaxMultiplierCollapsingToolbarLayout伸缩时,子视图的视觉差,可以通过属性app:layout_collapseParallaxMultiplier=”0.6”改变。值的范围[0.0,1.0],值越大视差越大。

  • app:collapsedTitleGravity:
    表示折叠时候title的位置,默认为left;

  • -app:expandedTitleGravity:
    表示展开时title的位置,默认为left+bottom;

下面我们看看布局实例:

<?xml version="1.0" encoding="utf-8"?>
<layout     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.support.design.widget.CoordinatorLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:fitsSystemWindows="true"
        tools:context="com.android.srx.github.designsupportlibrarydemo.CoordinatorLayoutActivity">
        <android.support.design.widget.AppBarLayout
            android:id="@+id/appbar"
            android:layout_width="match_parent"
            android:layout_height="200dp"
            android:fitsSystemWindows="true">

            <android.support.design.widget.CollapsingToolbarLayout
                android:id="@+id/collapsing_toolbar"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:fitsSystemWindows="true"
                app:contentScrim="@color/colorPrimary"
                app:expandedTitleMarginEnd="64dp"
                app:expandedTitleMarginStart="48dp"
                app:layout_scrollFlags="scroll|exitUntilCollapsed"
                >

                <ImageView
                    android:id="@+id/background_img"
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                    android:fitsSystemWindows="true"
                    android:scaleType="centerCrop"
                    android:src="@drawable/bg_material_design"/>
                <android.support.v7.widget.Toolbar
                    android:id="@+id/toolbar"
                    android:layout_width="match_parent"
                    android:layout_height="?attr/actionBarSize"
                    app:layout_collapseMode="pin"/>
            </android.support.design.widget.CollapsingToolbarLayout>

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

        <android.support.v7.widget.RecyclerView
            android:id="@+id/recycler_view"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:scrollbars="none"
            app:layout_behavior="@string/appbar_scrolling_view_behavior"
            />
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_gravity="bottom"
            android:background="@android:color/holo_blue_dark"
            android:gravity="center_horizontal"
            android:padding="15dp"
            app:layout_behavior="com.android.srx.github.designsupportlibrarydemo.FooterBehaviorAppBar">
            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:textColor="@android:color/white"
                android:text="Custom Behavior"/>

        </LinearLayout>

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

布局文件中,Toolbar定义了属性
app:layout_collapseMode="pin”,该属性表示子视图的折叠模式,在子视图设置,有两种

  • “pin”:固定模式,在折叠的时候最后固定在顶端;
  • “parallax”:视差模式,在折叠的时候会有个视差折叠的效果。

使用CollapsingToolbarLayout实现折叠效果,需要注意2点

  1. AppBarLayout的高度固定
  2. CollapsingToolbarLayout的子视图设置layout_collapseMode属性
  3. 有子控件发出滚动事件,比如这这里的RecyclerView

折叠效果如下:


Toobar的折叠效果

Java代码很简单,就直接给出代码:

public class CoordinatorLayoutActivity extends AppCompatActivity {
    private ActivityCoordinatorLayoutBinding mBinding;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mBinding = DataBindingUtil.setContentView(this,R.layout.activity_coordinator_layout);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
        initView();
    }

    private void initView() {
        mBinding.collapsingToolbar.setTitle("Design");
        mBinding.recyclerView.setLayoutManager(new LinearLayoutManager(this));
        mBinding.recyclerView.setAdapter(
                new ListAdapter(this, new StringGenerator("Item ").generateList(50)));
    }


}

注意为了便捷,这里作者使用了DataBinding。

3. 自定义Behavior

读者可能已经发现了,这里的不光是Toolbar一起响应滚动事件而伸缩,下面还有一个控件也在一起浮现和消失,这就是自定义Behavior,也是CoordinatorLayout最经典的地方。

自定义的Behavior都要继承自CoordinatorLayout.Behavior<View>
Behavior类中有一下函数需要说明:

  1. layoutDependsOn():用来确定关联的视图;
  2. onDependentViewChanged():当关联视图发生改变时回调接口;
  3. onDependentViewRemoved():关联视图移除时回调接口。

自定义Behavior需要注意的地方:

  1. 需要实现构造方法public Behavior(Context context, AttributeSet attrs),不然布局中无法使用;
  2. 关联的视图除了layoutDependsOn()指定的视图外还包括layout_anchor属性指定的视图,如果有多个依赖试图,可在onDependentViewChanged()方法中用instanceof判断;
  3. onDependentViewChanged()方法执行需要关联的视图大小位置改变
  4. 除了和关联视图做交互动画外,还能通过检测滚动来做交互动画;

下面是自定义Behavior的代码:

public class FooterBehaviorAppBar extends CoordinatorLayout.Behavior<View> {
    public FooterBehaviorAppBar(Context context, AttributeSet attrs) {
        super(context, attrs);
    }
    @Override
    public boolean layoutDependsOn(CoordinatorLayout parent, View child, View dependency) {
        return dependency instanceof AppBarLayout;
    }
    @Override
    public boolean onDependentViewChanged(CoordinatorLayout parent, View child, View dependency) {
        float translationY = Math.abs(dependency.getY());
        Log.i("wangshu",translationY+"");
        child.setTranslationY(translationY);
        return true;
    }
}

在实现中,我们关注的方法是layoutDependsOn()onDependentViewChanged():

  • layoutDependsOn方法用来判断该Behavior的发生依赖于哪个View,这很明确的指出,我们要依赖于AppBarLayout控件;
  • onDependentViewChanged方法实现让所依赖的View发生变化(位置或者是大小)时,目标View该如何变化。这里实现的是AppToolbarY轴上位移多少,目标View也跟着向下移动多少。

最后实现的效果就是二者同时出现,或者同时消失


同时出现

同时消失

参考文献:

  1. CoordinatorLayout 属性的使用介绍
  2. CoordinatorLayout自定义Behavior的运用

更多关于Design Support Library中控件的讲解将会在持续更新,欢迎关注。
最后给出Github源码

相关文章
|
4月前
|
存储 Java 数据库
Android数据存储:什么是Room Persistence Library?
Android数据存储:什么是Room Persistence Library?
91 0
|
Android开发
IDEA编译gradle提示This version of the Android Support plugin for IntelliJ IDEA (or Android Studio) cannot open this project, please retry with version 2020.3.1 or newer.
IDEA编译gradle提示This version of the Android Support plugin for IntelliJ IDEA (or Android Studio) cannot open this project, please retry with version 2020.3.1 or newer.
839 1
|
1月前
|
开发工具 Android开发
解决Android运行出现NDK at /Library/Android/sdk/ndk-bundle did not have a source.properties file
解决Android运行出现NDK at /Library/Android/sdk/ndk-bundle did not have a source.properties file
134 4
解决Android运行出现NDK at /Library/Android/sdk/ndk-bundle did not have a source.properties file
|
2月前
|
XML Android开发 UED
💥Android UI设计新风尚!掌握Material Design精髓,让你的界面颜值爆表!🎨
【7月更文挑战第28天】随着移动应用市场的发展,用户对界面设计的要求不断提高。Material Design是由Google推出的设计语言,强调真实感、统一性和创新性,通过模拟纸张和墨水的物理属性创造沉浸式体验。它注重色彩、排版、图标和布局的一致性,确保跨设备的统一视觉风格。Android Studio提供了丰富的Material Design组件库,如按钮、卡片等,易于使用且美观。
87 1
|
Android开发
Android面试常客之Handler全解1
Android面试常客之Handler全解
|
消息中间件 Android开发
Android面试常客之Handler全解2
Android面试常客之Handler全解
|
Android开发 开发者 UED
Android Design Support Library初探-更新中
Android Design Support Library初探-更新中
90 0
|
XML Java 开发工具
Android5.0新特性-Material Design
Android5.0新特性-Material Design
79 0
|
Android开发
Unrecognized Android Studio (or Android Support plugin for IntelliJ IDEA) version ‘202.7660.26.42.74
Unrecognized Android Studio (or Android Support plugin for IntelliJ IDEA) version ‘202.7660.26.42.74
304 0
Unrecognized Android Studio (or Android Support plugin for IntelliJ IDEA) version ‘202.7660.26.42.74
|
开发工具 Android开发
Android Support Design Library之FloatingActionButton(二)
Android Support Design Library之FloatingActionButton(二)
71 0
Android Support Design Library之FloatingActionButton(二)