viewAndroid开发之路Material Design

CoordinatorLayout与Behavior的实际使用(

2017-03-12  本文已影响472人  fodroid

CoordinatorLayout有什么用

在 2015 年的 I/O 开发者大会上,Google 介绍了一个新的 Android Design Support Library,该库可以帮助开发者在应用上使用 Meterial Design。它包含了许多重要的 Meterial Design 的构建块,并且它支持 API 7及以上的版本。 在库中就包含一个CoordinatorLayout,它是一个 FrameLayout。该布局的强大在于,能够协调子元素之间的依赖关系。CoordinatorLayout使用新的思路通过协调调度子布局的形式实现触摸影响布局的形式产生动画效果。CoordinatorLayout通过设置子ViewBehaviors来调度子View。Library中提供了AppBarLayout.Behavior, AppBarLayout.ScrollingViewBehavior, FloatingActionButton.Behavior, SwipeDismissBehavior<V extends View> 等。

CoordinatorLayout如何使用

使用CoordinatorLayout需要在app目录中build.gradle加入Support Design Library:

compile 'com.android.support:design:25.1.0'

接下来我们看看官方的效果,首先我们新建一个项目,然后在Add an Activity to Mobile中选择Scrolling Activity

Paste_Image.png

接下来我们看一看Android Studio自动帮我们生成的代码。

activity_scrolling.xml

<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"
    android:fitsSystemWindows="true"
    tools:context="me.shihao.coordinatorlayoutusage.ScrollingActivity">

    <android.support.design.widget.AppBarLayout
        android:id="@+id/app_bar"
        android:layout_width="match_parent"
        android:layout_height="@dimen/app_bar_height"
        android:fitsSystemWindows="true"
        android:theme="@style/AppTheme.AppBarOverlay">

        <android.support.design.widget.CollapsingToolbarLayout
            android:id="@+id/toolbar_layout"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:fitsSystemWindows="true"
            app:contentScrim="?attr/colorPrimary"
            app:layout_scrollFlags="scroll|exitUntilCollapsed">

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

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

    <android.support.design.widget.FloatingActionButton
        android:id="@+id/fab"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_margin="@dimen/fab_margin"
        app:layout_anchor="@id/app_bar"
        app:layout_anchorGravity="bottom|end"
        app:srcCompat="@android:drawable/ic_dialog_email"/>

    <include layout="@layout/content_scrolling"/>

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

<a name="1"></a>
content_scrolling.xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.NestedScrollView
    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"
    app:layout_behavior="@string/appbar_scrolling_view_behavior"
    tools:context="me.shihao.coordinatorlayoutusage.ScrollingActivity"
    tools:showIn="@layout/activity_scrolling">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_margin="@dimen/text_margin"
        android:text="@string/large_text"/>

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

ScrollingActivity.java

public class ScrollingActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_scrolling);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
                        .setAction("Action", null).show();
            }
        });
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_scrolling, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            return true;
        }
        return super.onOptionsItemSelected(item);
    }
}

运行效果

运行效果.gif

效果显示,视图滚动时Toolbar会折叠,这个效果是Android Support Library里面新增的CoordinatorLayout, AppBarLayoutCollapsingToolbarLayout实现的。根据官方的文档,AppBarLayout必须是CoordinatorLayout的直接子View。然后,我们需要定义AppBarLayout与滚动视图之间的联系。在content_scrolling.xml中为可滚动视图NestedScrollView的添加了app:layout_behavior。support library包含了一个特殊的字符串资源@string/appbar_scrolling_view_behavior,它和AppBarLayout.ScrollingViewBehavior相匹配,用来通知AppBarLayout 这个特殊的view何时发生了滚动事件,这个behavior需要设置在触发事件(滚动)的view之上。当CoordinatorLayout发现NestedScrollView中定义了这个属性,它会搜索自己所包含的其他view,看看是否有view与这个behavior相关联。AppBarLayout.ScrollingViewBehavior描述了NestedScrollViewAppBarLayout之间的依赖关系。NestedScrollView的任意滚动事件都将触发AppBarLayout或者AppBarLayout里面view的改变。AppBarLayout里面定义的view只要设置了app:layout_scrollFlags属性,就可以在NestedScrollView滚动事件发生的时候被触发。

CollapsingToolbarLayout

CollapsingToolbarLayout作用是提供了一个可以折叠的Toolbar,它继承至FrameLayout,给它设置layout_scrollFlags,它可以控制包含在CollapsingToolbarLayout中的控件(如:ImageViewToolbar)在响应layout_behavior事件时作出相应的scrollFlags滚动事件(移除屏幕或固定在屏幕顶端)。CollapsingToolbarLayout提供以下属性和方法使用:

app:layout_scrollFlags

app:layout_scrollFlags属性里面必须至少启用scroll这个flag,这样这个view才会滚动,否则它将一直固定在顶部。并且要把带有scroll flagview放在前面,这样收回的view才能让正常退出,而固定的view继续留在顶部。可以使用的其他flag有:

CoordinatorLayout还提供了一个layout_anchor的属性,连同 layout_anchorGravity一起,可以用来放置与其他视图关联在一起的悬浮视图(如 FloatingActionButton)。如本例中使用FloatingActionButton。通过下面的参数设置了FloatingActionButton的位置,两个属性共同作用使得浮动按钮也能折叠消失展现。

app:layout_anchor="@id/appbar"
app:layout_anchorGravity="bottom|right|end"

总结

实现折叠效果,需要注意下面几点:

  1. 顶层布局为CoordinatorLayout
  2. AppBarLayout的高度固定。
  3. CollapsingToolbarLayout的子视图设置app:layout_scrollFlags属性
  4. 关联滚动视图(如本例中的NestedScrollView)设置属性app:layout_behavior
  5. 关联悬浮视图(如本例中的FloatingActionButton)设置app:layout_anchorapp:layout_anchorGravity属性

当然CoordinatorLayout功能还强大,而他的神奇之处在于Behavior对象,CoordinatorLayout自己并不控制View,所有的控制权都在Behavior。比如前面用到的FloatingActionButton.BehaviorAppBarLayout.Behavior, AppBarLayout.ScrollingViewBehavior。当然我们可以通过自定义的方式来实现自己的Behavior,来实现更多样的功能。自定义Behavior使用请查看:

CoordinatorLayout与Behavior的实际使用(二)


Demo已经放在了Github上,传送门:CoordinatorLayoutUsage

如果你觉得有用,请在Github不吝给我一个Star,非常感谢。


写在最后的话:个人能力有限,欢迎大家在下面吐槽。喜欢的话就为我点一个赞吧。也欢迎 Fork Me On Github 。

上一篇下一篇

猜你喜欢

热点阅读